Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / client / gui-xaw / connectdlg.c
blob87f9a9c2d58bae9473b907fcb7abccd485b4b24f
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 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
22 #include <X11/Intrinsic.h>
23 #include <X11/StringDefs.h>
24 #include <X11/Xaw/Form.h>
25 #include <X11/Xaw/Label.h>
26 #include <X11/Xaw/SimpleMenu.h>
27 #include <X11/Xaw/Command.h>
28 #include <X11/Xaw/AsciiText.h>
29 #include <X11/Xaw/List.h>
30 #include <X11/Xaw/Viewport.h>
32 /* common & utility */
33 #include "fcintl.h"
34 #include "log.h"
35 #include "mem.h" /* fc_strdup() */
36 #include "support.h"
37 #include "version.h"
39 /* client */
40 #include "client_main.h"
41 #include "clinet.h" /* connect_to_server() */
42 #include "packhand.h"
43 #include "servers.h"
45 #include "chatline.h"
46 #include "gui_main.h"
47 #include "gui_stuff.h"
48 #include "pages.h"
50 #include "connectdlg_common.h"
51 #include "connectdlg.h"
54 enum connection_state {
55 LOGIN_TYPE,
56 NEW_PASSWORD_TYPE,
57 ENTER_PASSWORD_TYPE,
58 WAITING_TYPE
61 static enum connection_state connection_status;
64 static Widget connectdlg_shell;
65 static Widget connectdlg_form;
66 #if IS_BETA_VERSION
67 static Widget connectdlg_beta_label;
68 #endif
69 static Widget connectdlg_select_label;
70 static Widget connectdlg_host_label;
71 static Widget connectdlg_host_text;
72 static Widget connectdlg_port_label;
73 static Widget connectdlg_port_text;
74 static Widget connectdlg_login_label;
75 static Widget connectdlg_login_text;
76 static Widget connectdlg_password_label;
77 static Widget connectdlg_password_text;
78 static Widget connectdlg_verify_label;
79 static Widget connectdlg_verify_text;
80 static Widget connectdlg_message_label;
81 static Widget connectdlg_connect_button;
82 static Widget connectdlg_lan_button;
83 static Widget connectdlg_meta_button;
84 static Widget connectdlg_quit_button;
86 void connectdlg_connect_callback(Widget w, XtPointer client_data,
87 XtPointer call_data);
88 void connectdlg_lan_callback(Widget w, XtPointer client_data,
89 XtPointer call_data);
90 void connectdlg_meta_callback(Widget w, XtPointer client_data,
91 XtPointer call_data);
92 void connectdlg_quit_callback(Widget w, XtPointer client_data,
93 XtPointer call_data);
95 /****************************************************************/
97 /* Serverlist */
98 static Widget connectdlg_serverlist_shell;
100 static Widget connectdlg_serverlist_form;
101 static Widget connectdlg_serverlist_legend_label;
102 static Widget connectdlg_serverlist_viewport;
103 static Widget connectdlg_serverlist_list;
104 static Widget connectdlg_serverlist_update_button;
105 static Widget connectdlg_serverlist_close_button;
107 static struct server_scan *lan_scan, *meta_scan;
109 void connectdlg_serverlist_popup(void);
110 void server_scan_error(struct server_scan *scan, const char *message);
111 void connectdlg_serverlist_update_callback(Widget w, XtPointer client_data,
112 XtPointer call_data);
113 void connectdlg_serverlist_close_callback(Widget w, XtPointer client_data,
114 XtPointer call_data);
115 void connectdlg_serverlist_list_callback(Widget w, XtPointer client_data,
116 XtPointer call_data);
118 /* FIXME: Replace magic 64 with proper constant. */
119 static char *servers_list[64]={NULL};
121 static void server_list_timer(XtPointer client_data, XtIntervalId * id);
122 static int get_server_list(char **list, char *errbuf, int n_errbuf);
124 static bool lan_mode; /* true for LAN mode, false when Meta mode */
125 static int num_lanservers_timer = 0;
128 /****************************************************************************
129 Aligns widths of connect dialog labels and texts.
130 ****************************************************************************/
131 static void connectdlg_align_labels(void)
133 Dimension width, s_width, t_width, max_width = 0;
135 #if IS_BETA_VERSION
136 XtVaGetValues(connectdlg_beta_label, XtNwidth, &width, NULL);
137 max_width = width;
138 #endif
140 XtVaGetValues(connectdlg_select_label, XtNwidth, &width, NULL);
141 if (width > max_width) {
142 max_width = width;
144 XtVaGetValues(connectdlg_message_label, XtNwidth, &width, NULL);
145 if (width > max_width) {
146 max_width = width;
149 /* FIXME: Replace 7 with proper XtN* variable value */
150 XtVaGetValues(connectdlg_host_label, XtNwidth, &width, NULL);
151 XtVaGetValues(connectdlg_host_text, XtNwidth, &t_width, NULL);
152 s_width = width;
153 if (width + 7 + t_width > max_width) {
154 max_width = width + 7 + t_width;
156 XtVaGetValues(connectdlg_port_label, XtNwidth, &width, NULL);
157 XtVaGetValues(connectdlg_port_text, XtNwidth, &t_width, NULL);
158 if (width > s_width) {
159 s_width = width;
161 if (width + 7 + t_width > max_width) {
162 max_width = width + 7 + t_width;
164 XtVaGetValues(connectdlg_login_label, XtNwidth, &width, NULL);
165 XtVaGetValues(connectdlg_login_text, XtNwidth, &t_width, NULL);
166 if (width > s_width) {
167 s_width = width;
169 if (width + 7 + t_width > max_width) {
170 max_width = width + 7 + t_width;
172 XtVaGetValues(connectdlg_password_label, XtNwidth, &width, NULL);
173 XtVaGetValues(connectdlg_password_text, XtNwidth, &t_width, NULL);
174 if (width > s_width) {
175 s_width = width;
177 if (width + 7 + t_width > max_width) {
178 max_width = width + 7 + t_width;
180 XtVaGetValues(connectdlg_verify_label, XtNwidth, &width, NULL);
181 XtVaGetValues(connectdlg_verify_text, XtNwidth, &t_width, NULL);
182 if (width > s_width) {
183 s_width = width;
185 if (width + 7 + t_width > max_width) {
186 max_width = width + 7 + t_width;
189 #if IS_BETA_VERSION
190 XtVaSetValues(connectdlg_beta_label, XtNwidth, max_width, NULL);
191 #endif
192 XtVaSetValues(connectdlg_select_label, XtNwidth, max_width, NULL);
193 XtVaSetValues(connectdlg_message_label, XtNwidth, max_width, NULL);
194 XtVaSetValues(connectdlg_message_label, XtNresizable, False, NULL);
196 XtVaSetValues(connectdlg_host_label, XtNwidth, s_width, NULL);
197 XtVaSetValues(connectdlg_port_label, XtNwidth, s_width, NULL);
198 XtVaSetValues(connectdlg_login_label, XtNwidth, s_width, NULL);
199 XtVaSetValues(connectdlg_password_label, XtNwidth, s_width, NULL);
200 XtVaSetValues(connectdlg_verify_label, XtNwidth, s_width, NULL);
202 XtVaSetValues(connectdlg_host_text, XtNresizable, True, NULL);
203 XtVaSetValues(connectdlg_host_text, XtNwidth, max_width - s_width - 7,
204 NULL);
205 XtVaSetValues(connectdlg_host_text, XtNresizable, False, NULL);
206 XtVaSetValues(connectdlg_port_text, XtNresizable, True, NULL);
207 XtVaSetValues(connectdlg_port_text, XtNwidth, max_width - s_width - 7,
208 NULL);
209 XtVaSetValues(connectdlg_port_text, XtNresizable, False, NULL);
210 XtVaSetValues(connectdlg_login_text, XtNresizable, True, NULL);
211 XtVaSetValues(connectdlg_login_text, XtNwidth, max_width - s_width - 7,
212 NULL);
213 XtVaSetValues(connectdlg_login_text, XtNresizable, False, NULL);
214 XtVaSetValues(connectdlg_password_text, XtNresizable, True, NULL);
215 XtVaSetValues(connectdlg_password_text, XtNwidth, max_width - s_width - 7,
216 NULL);
217 XtVaSetValues(connectdlg_password_text, XtNresizable, False, NULL);
218 XtVaSetValues(connectdlg_verify_text, XtNresizable, True, NULL);
219 XtVaSetValues(connectdlg_verify_text, XtNwidth, max_width - s_width - 7,
220 NULL);
221 XtVaSetValues(connectdlg_verify_text, XtNresizable, False, NULL);
224 /**************************************************************************
225 Creates connect dialog.
226 **************************************************************************/
227 static void connectdlg_create(void)
229 char buf[64];
231 if (connectdlg_shell) {
232 return;
235 connectdlg_shell =
236 I_IN(I_T(XtCreatePopupShell("connectdialog", topLevelShellWidgetClass,
237 toplevel, NULL, 0)));
238 connectdlg_form =
239 XtVaCreateManagedWidget("connectform", formWidgetClass,
240 connectdlg_shell, NULL);
242 #if IS_BETA_VERSION
243 connectdlg_beta_label =
244 I_L(XtVaCreateManagedWidget("connbetalabel", labelWidgetClass,
245 connectdlg_form,
246 XtNresizable, True,
247 XtNjustify, XtJustifyCenter,
248 XtNlabel, beta_message(),
249 NULL));
250 #endif
252 connectdlg_select_label =
253 I_L(XtVaCreateManagedWidget("connselectlabel", labelWidgetClass,
254 connectdlg_form,
255 XtNresizable, True,
256 #if IS_BETA_VERSION
257 XtNfromVert, connectdlg_beta_label,
258 #endif
259 NULL));
261 connectdlg_host_label =
262 I_L(XtVaCreateManagedWidget("connhostlabel", labelWidgetClass,
263 connectdlg_form,
264 XtNresizable, True,
265 NULL));
266 connectdlg_host_text =
267 XtVaCreateManagedWidget("connhosttext", asciiTextWidgetClass,
268 connectdlg_form,
269 XtNeditType, XawtextEdit,
270 XtNstring, server_host,
271 NULL);
272 connectdlg_port_label =
273 I_L(XtVaCreateManagedWidget("connportlabel", labelWidgetClass,
274 connectdlg_form,
275 XtNresizable, True,
276 NULL));
277 fc_snprintf(buf, sizeof(buf), "%d", server_port);
278 connectdlg_port_text =
279 XtVaCreateManagedWidget("connporttext", asciiTextWidgetClass,
280 connectdlg_form,
281 XtNeditType, XawtextEdit,
282 XtNstring, buf,
283 NULL);
284 connectdlg_login_label =
285 I_L(XtVaCreateManagedWidget("connloginlabel", labelWidgetClass,
286 connectdlg_form,
287 XtNresizable, True,
288 NULL));
289 connectdlg_login_text =
290 XtVaCreateManagedWidget("connlogintext", asciiTextWidgetClass,
291 connectdlg_form,
292 XtNeditType, XawtextEdit,
293 XtNstring, user_name,
294 NULL);
295 connectdlg_password_label =
296 I_L(XtVaCreateManagedWidget("connpasswordlabel", labelWidgetClass,
297 connectdlg_form,
298 XtNresizable, True,
299 NULL));
300 connectdlg_password_text =
301 XtVaCreateManagedWidget("connpasswordtext", asciiTextWidgetClass,
302 connectdlg_form,
303 XtNecho, False,
304 XtNsensitive, False,
305 NULL);
306 connectdlg_verify_label =
307 I_L(XtVaCreateManagedWidget("connverifylabel", labelWidgetClass,
308 connectdlg_form,
309 XtNresizable, True,
310 NULL));
311 connectdlg_verify_text =
312 XtVaCreateManagedWidget("connverifytext", asciiTextWidgetClass,
313 connectdlg_form,
314 XtNecho, False,
315 XtNsensitive, False,
316 NULL);
317 connectdlg_message_label =
318 I_L(XtVaCreateManagedWidget("connmessagelabel", labelWidgetClass,
319 connectdlg_form,
320 XtNresizable, True,
321 NULL));
323 connectdlg_connect_button =
324 I_L(XtVaCreateManagedWidget("connconnectbutton", commandWidgetClass,
325 connectdlg_form,
326 XtNlabel, _("Connect"),
327 NULL));
328 connectdlg_lan_button =
329 I_L(XtVaCreateManagedWidget("connlanbutton", commandWidgetClass,
330 connectdlg_form,
331 XtNlabel, _("LAN Servers"),
332 NULL));
333 connectdlg_meta_button =
334 I_L(XtVaCreateManagedWidget("connmetabutton", commandWidgetClass,
335 connectdlg_form,
336 XtNlabel, _("Metaserver"),
337 NULL));
338 connectdlg_quit_button =
339 I_L(XtVaCreateManagedWidget("connquitbutton", commandWidgetClass,
340 connectdlg_form,
341 XtNlabel, _("Quit"),
342 NULL));
344 XtAddCallback(connectdlg_connect_button, XtNcallback,
345 connectdlg_connect_callback, NULL);
346 XtAddCallback(connectdlg_lan_button, XtNcallback,
347 connectdlg_lan_callback, NULL);
348 XtAddCallback(connectdlg_meta_button, XtNcallback,
349 connectdlg_meta_callback, NULL);
350 XtAddCallback(connectdlg_quit_button, XtNcallback,
351 connectdlg_quit_callback, NULL);
353 XtRealizeWidget(connectdlg_shell);
356 /**************************************************************************
357 Popdowns connect dialog.
358 **************************************************************************/
359 static void connectdlg_popdown(void)
361 if (lan_scan) {
362 server_scan_finish(lan_scan);
363 lan_scan = NULL;
365 if (meta_scan) {
366 server_scan_finish(meta_scan);
367 meta_scan = NULL;
369 if (connectdlg_shell) {
370 XtPopdown(connectdlg_shell);
374 /**************************************************************************
375 Destroys connect dialog.
376 **************************************************************************/
377 static void connectdlg_destroy(void)
379 if (connectdlg_shell) {
380 connectdlg_popdown();
381 XtDestroyWidget(connectdlg_shell);
382 connectdlg_shell = NULL;
386 /**************************************************************************
387 Popups connect dialog.
388 **************************************************************************/
389 static void connectdlg_popup(void)
391 if (!connectdlg_shell) {
392 connectdlg_create();
395 connectdlg_align_labels();
396 xaw_set_relative_position(toplevel, connectdlg_shell, 20, 20);
397 XtPopup(connectdlg_shell, XtGrabNone);
400 /****************************************************************************
401 Callback for Connect button.
402 ****************************************************************************/
403 void connectdlg_connect_callback(Widget w, XtPointer client_data,
404 XtPointer call_data)
406 XtPointer pxp;
407 char errbuf[512];
408 struct packet_authentication_reply reply;
410 switch (connection_status) {
411 case LOGIN_TYPE:
412 XtVaGetValues(connectdlg_host_text, XtNstring, &pxp, NULL);
413 sz_strlcpy(server_host, (char *)pxp);
414 XtVaGetValues(connectdlg_port_text, XtNstring, &pxp, NULL);
415 sscanf((char *)pxp, "%d", &server_port);
416 XtVaGetValues(connectdlg_login_text, XtNstring, &pxp, NULL);
417 sz_strlcpy(user_name, (char *)pxp);
418 if (connect_to_server(user_name, server_host, server_port,
419 errbuf, sizeof(errbuf)) != -1) {
420 popup_start_page();
421 connectdlg_destroy();
422 XtSetSensitive(toplevel, True);
423 return;
424 } else {
425 XtVaSetValues(connectdlg_message_label, XtNlabel, errbuf, NULL);
426 output_window_append(ftc_client, errbuf);
428 break;
429 case NEW_PASSWORD_TYPE:
430 XtVaGetValues(connectdlg_password_text, XtNstring, &pxp, NULL);
431 sz_strlcpy(password, (char *)pxp);
432 XtVaGetValues(connectdlg_verify_text, XtNstring, &pxp, NULL);
433 sz_strlcpy(reply.password, (char *)pxp);
434 if (strncmp(reply.password, password, MAX_LEN_NAME) == 0) {
435 password[0] = '\0';
436 send_packet_authentication_reply(&client.conn, &reply);
437 XtVaSetValues(connectdlg_message_label, XtNlabel, "", NULL);
438 XtVaSetValues(connectdlg_password_text, XtNsensitive, False, NULL);
439 XtVaSetValues(connectdlg_verify_text, XtNsensitive, False, NULL);
440 } else {
441 XtVaSetValues(connectdlg_password_text, XtNstring, "", NULL);
442 XtVaSetValues(connectdlg_verify_text, XtNstring, "", NULL);
443 XtVaSetValues(connectdlg_message_label, XtNlabel,
444 _("Passwords don't match, enter password."), NULL);
445 output_window_append(ftc_client,
446 _("Passwords don't match, enter password."));
448 break;
449 case ENTER_PASSWORD_TYPE:
450 XtVaGetValues(connectdlg_verify_text, XtNstring, &pxp, NULL);
451 sz_strlcpy(reply.password, (char *)pxp);
452 send_packet_authentication_reply(&client.conn, &reply);
454 XtVaSetValues(connectdlg_message_label, XtNlabel, "", NULL);
455 XtVaSetValues(connectdlg_password_text, XtNsensitive, False, NULL);
456 XtVaSetValues(connectdlg_verify_text, XtNsensitive, False, NULL);
457 break;
458 case WAITING_TYPE:
459 break;
463 /****************************************************************************
464 Callback fir LAN Servers button.
465 ****************************************************************************/
466 void connectdlg_lan_callback(Widget w, XtPointer client_data,
467 XtPointer call_data)
469 lan_mode = true;
470 if (!lan_scan) {
471 lan_scan = server_scan_begin(SERVER_SCAN_LOCAL, server_scan_error);
473 connectdlg_serverlist_popup();
476 /****************************************************************************
477 Callback for Metaserver button.
478 ****************************************************************************/
479 void connectdlg_meta_callback(Widget w, XtPointer client_data,
480 XtPointer call_data)
482 lan_mode = false;
483 if (!meta_scan) {
484 meta_scan = server_scan_begin(SERVER_SCAN_GLOBAL, server_scan_error);
486 connectdlg_serverlist_popup();
489 /****************************************************************************
490 Callback for Quit button.
491 ****************************************************************************/
492 void connectdlg_quit_callback(Widget w, XtPointer client_data,
493 XtPointer call_data)
495 connectdlg_destroy();
496 xaw_ui_exit();
499 /**************************************************************************
500 configure the dialog depending on what type of authentication request the
501 server is making.
502 **************************************************************************/
503 void handle_authentication_req(enum authentication_type type,
504 const char *message)
506 XtVaSetValues(connectdlg_message_label, XtNlabel, message, NULL);
508 switch (type) {
509 case AUTH_NEWUSER_FIRST:
510 case AUTH_NEWUSER_RETRY:
511 XtVaSetValues(connectdlg_password_text, XtNsensitive, True, NULL);
512 XtVaSetValues(connectdlg_verify_text, XtNsensitive, True, NULL);
513 connection_status = NEW_PASSWORD_TYPE;
514 break;
515 case AUTH_LOGIN_FIRST:
516 /* if we magically have a password already present in 'password'
517 * then, use that and skip the password entry dialog */
518 if (password[0] != '\0') {
519 struct packet_authentication_reply reply;
521 sz_strlcpy(reply.password, password);
522 send_packet_authentication_reply(&client.conn, &reply);
523 return;
524 } else {
525 XtVaSetValues(connectdlg_password_text, XtNsensitive, True, NULL);
526 XtVaSetValues(connectdlg_verify_text, XtNsensitive, False, NULL);
527 connection_status = ENTER_PASSWORD_TYPE;
529 break;
530 case AUTH_LOGIN_RETRY:
531 XtVaSetValues(connectdlg_password_text, XtNsensitive, True, NULL);
532 XtVaSetValues(connectdlg_verify_text, XtNsensitive, False, NULL);
533 connection_status = ENTER_PASSWORD_TYPE;
534 break;
535 default:
536 log_error("Unsupported authentication type %d: %s.", type, message);
537 break;
541 /****************************************************************
542 Provide an interface for connecting to a Freeciv server.
543 *****************************************************************/
544 void server_connect(void)
546 connection_status = LOGIN_TYPE;
548 XtSetSensitive(turn_done_button, FALSE);
549 /* XtSetSensitive(toplevel, FALSE);*/
551 if (auto_connect) {
552 /* FIXME */
553 } else {
554 connectdlg_popup();
556 XtPopup(connectdlg_shell, XtGrabNone);
557 XtSetKeyboardFocus(toplevel, connectdlg_shell);
562 /**************************************************************************
563 this regenerates the player information from a loaded game on the server.
564 currently a stub. TODO
565 **************************************************************************/
566 void handle_game_load(bool load_successful, const char *filename)
568 /* PORTME */
571 /****************************************************************
573 *****************************************************************/
574 void connectdlg_key_connect(Widget w)
576 x_simulate_button_click(connectdlg_connect_button);
579 /****************************************************************************
580 SERVERS LIST DIALOG
581 ****************************************************************************/
583 /****************************************************************************
584 Callback function for when there's an error in the server scan.
585 ****************************************************************************/
586 void server_scan_error(struct server_scan *scan, const char *message)
588 output_window_append(ftc_client, message);
589 log_normal("%s", message);
590 switch (server_scan_get_type(scan)) {
591 case SERVER_SCAN_LOCAL:
592 server_scan_finish(lan_scan);
593 lan_scan = NULL;
594 break;
595 case SERVER_SCAN_GLOBAL:
596 server_scan_finish(meta_scan);
597 meta_scan = NULL;
598 break;
599 case SERVER_SCAN_LAST:
600 break;
604 /****************************************************************************
605 This function updates the list of servers after the server dialog has been
606 displayed. LAN servers updated every 250 ms for 5 seconds, metaserver
607 updated every 500 ms for 2 seconds.
608 ****************************************************************************/
609 static void server_list_timer(XtPointer meta_list, XtIntervalId * id)
611 char errbuf[128];
613 if (!connectdlg_serverlist_shell) {
614 return;
617 if (get_server_list(servers_list, errbuf, sizeof(errbuf)) != -1) {
618 XawListChange(meta_list, servers_list, 0, 0, True);
621 else if (!lan_mode) {
622 output_window_append(ftc_client, errbuf);
625 num_lanservers_timer++;
627 if (lan_mode) {
628 if (num_lanservers_timer == 20) {
629 server_scan_finish(lan_scan);
630 lan_scan = NULL;
631 num_lanservers_timer = 0;
632 return;
634 (void)XtAppAddTimeOut(app_context, 250, server_list_timer,
635 (XtPointer)meta_list);
636 } else {
637 if (num_lanservers_timer == 4) {
638 server_scan_finish(meta_scan);
639 meta_scan = NULL;
640 num_lanservers_timer = 0;
641 return;
643 (void)XtAppAddTimeOut(app_context, 500, server_list_timer,
644 (XtPointer)meta_list);
648 /****************************************************************************
649 Creates Servers List dialog.
650 ****************************************************************************/
651 static void connectdlg_serverlist_create(void)
653 connectdlg_serverlist_shell =
654 I_IN(I_T(XtCreatePopupShell("serverlistdialog",
655 topLevelShellWidgetClass,
656 toplevel, NULL, 0)));
658 connectdlg_serverlist_form =
659 XtVaCreateManagedWidget("serverlistform", formWidgetClass,
660 connectdlg_serverlist_shell, NULL);
661 connectdlg_serverlist_legend_label =
662 I_L(XtVaCreateManagedWidget("legendlabel", labelWidgetClass,
663 connectdlg_serverlist_form,
664 XtNresizable, True,
665 NULL));
666 connectdlg_serverlist_viewport =
667 XtVaCreateManagedWidget("viewport", viewportWidgetClass,
668 connectdlg_serverlist_form, NULL);
669 connectdlg_serverlist_list =
670 XtVaCreateManagedWidget("serverlist", listWidgetClass,
671 connectdlg_serverlist_viewport, NULL);
672 connectdlg_serverlist_update_button =
673 XtVaCreateManagedWidget("updatebutton", commandWidgetClass,
674 connectdlg_serverlist_form,
675 XtNlabel, _("Update"),
676 NULL);
677 connectdlg_serverlist_close_button =
678 XtVaCreateManagedWidget("closebutton", commandWidgetClass,
679 connectdlg_serverlist_form,
680 XtNlabel, _("Close"),
681 NULL);
683 XtAddCallback(connectdlg_serverlist_update_button, XtNcallback,
684 connectdlg_serverlist_update_callback, NULL);
685 XtAddCallback(connectdlg_serverlist_close_button, XtNcallback,
686 connectdlg_serverlist_close_callback, NULL);
687 XtAddCallback(connectdlg_serverlist_list, XtNcallback,
688 connectdlg_serverlist_list_callback, NULL);
690 (void)XtAppAddTimeOut(app_context, 1, server_list_timer,
691 (XtPointer)connectdlg_serverlist_list);
693 XtRealizeWidget(connectdlg_serverlist_shell);
696 /****************************************************************************
697 Popups Servers List dialog.
698 ****************************************************************************/
699 void connectdlg_serverlist_popup(void)
701 if (!connectdlg_serverlist_shell) {
702 connectdlg_serverlist_create();
705 xaw_set_relative_position(toplevel, connectdlg_serverlist_shell, 15, 15);
706 XtPopup(connectdlg_serverlist_shell, XtGrabNone);
709 /****************************************************************************
710 Destroys Servers List dialog.
711 ****************************************************************************/
712 static void connectdlg_serverlist_destroy(void)
714 int i;
716 if (lan_scan) {
717 server_scan_finish(lan_scan);
718 lan_scan = NULL;
720 if (meta_scan) {
721 server_scan_finish(meta_scan);
722 meta_scan = NULL;
724 /* FIXME: Replace magic 64 with proper constant. */
725 for (i = 0; i < 64; i++) {
726 if (servers_list[i]) {
727 free(servers_list[i]);
728 servers_list[i] = NULL;
731 if (connectdlg_serverlist_shell) {
732 XtDestroyWidget(connectdlg_serverlist_shell);
733 connectdlg_serverlist_shell = NULL;
737 /****************************************************************************
738 Callback for Update button.
739 ****************************************************************************/
740 void connectdlg_serverlist_update_callback(Widget w, XtPointer client_data,
741 XtPointer call_data)
743 if (lan_mode) {
744 if (!lan_scan) {
745 lan_scan = server_scan_begin(SERVER_SCAN_LOCAL, server_scan_error);
747 if (num_lanservers_timer == 0) {
748 server_list_timer(connectdlg_serverlist_list, NULL);
750 } else {
751 if (!meta_scan) {
752 meta_scan = server_scan_begin(SERVER_SCAN_GLOBAL, server_scan_error);
754 if (num_lanservers_timer == 0) {
755 server_list_timer(connectdlg_serverlist_list, NULL);
760 /****************************************************************************
761 Callback for Close button.
762 ****************************************************************************/
763 void connectdlg_serverlist_close_callback(Widget w, XtPointer client_data,
764 XtPointer call_data)
766 connectdlg_serverlist_destroy();
769 /****************************************************************************
770 Callback for choosing server from serverlist.
771 ****************************************************************************/
772 void connectdlg_serverlist_list_callback(Widget w, XtPointer client_data,
773 XtPointer call_data)
775 XawListReturnStruct *ret = XawListShowCurrent(w);
776 char name[64], port[16];
778 sscanf(ret->string, "%s %s\n", name, port);
779 XtVaSetValues(connectdlg_host_text, XtNstring, name, NULL);
780 XtVaSetValues(connectdlg_port_text, XtNstring, port, NULL);
783 /**************************************************************************
784 Get the list of servers from the metaserver or LAN servers
785 depending on lan_mode.
786 **************************************************************************/
787 static int get_server_list(char **list, char *errbuf, int n_errbuf)
789 char line[256];
790 struct srv_list *srvrs = NULL;
791 enum server_scan_status scan_stat;
793 if (lan_mode) {
794 if (lan_scan) {
795 server_scan_poll(lan_scan);
796 srvrs = server_scan_get_list(lan_scan);
797 fc_allocate_mutex(&srvrs->mutex);
798 if (srvrs->servers == NULL) {
799 int retval;
801 if (num_lanservers_timer == 0) {
802 if (*list) {
803 free(*list);
805 *list = fc_strdup(" ");
806 retval = 0;
807 } else {
808 retval = -1;
810 fc_release_mutex(&srvrs->mutex);
812 return retval;
814 } else {
815 return -1;
817 } else {
818 if (meta_scan) {
819 scan_stat = server_scan_poll(meta_scan);
820 if (scan_stat >= SCAN_STATUS_PARTIAL) {
821 srvrs = server_scan_get_list(meta_scan);
822 fc_allocate_mutex(&srvrs->mutex);
823 if (!srvrs->servers) {
824 fc_release_mutex(&srvrs->mutex);
825 if (num_lanservers_timer == 0) {
826 if (*list) {
827 free(*list);
829 *list = fc_strdup(" ");
830 return 0;
831 } else {
832 return -1;
835 } else {
836 return -1;
838 } else {
839 return -1;
843 server_list_iterate(srvrs->servers, pserver) {
844 if (pserver == NULL) {
845 continue;
847 fc_snprintf(line, sizeof(line), "%-35s %-5d %-11s %-11s %2d %s",
848 pserver->host, pserver->port, pserver->version,
849 _(pserver->state), pserver->nplayers, pserver->message);
850 if (*list) {
851 free(*list);
853 *list = fc_strdup(line);
854 list++;
855 } server_list_iterate_end;
857 fc_release_mutex(&srvrs->mutex);
860 if (!lan_mode) {
861 delete_server_list(server_list);
864 *list = NULL;
866 return 0;
869 /**************************************************************************
870 Really closes and destroys the dialog.
871 **************************************************************************/
872 void really_close_connection_dialog(void)
874 /* PORTME */
877 /**************************************************************************
878 Closes and destroys the dialog.
879 **************************************************************************/
880 void close_connection_dialog()
882 connectdlg_serverlist_destroy();
883 connectdlg_destroy();