|
Crossfire Client, Trunk
R18666
|
00001 const char * const rcsid_gtk2_account_c = 00002 "$Id: account.c 14486 2011-05-23 17:57:22Z ryo_saeba $"; 00003 /* 00004 Crossfire client, a client program for the crossfire program. 00005 00006 Copyright (C) 2010 Mark Wedel & Crossfire Development Team 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 00022 The author can be reached via e-mail to crossfire@metalforge.org 00023 */ 00024 00030 #ifdef HAVE_CONFIG_H 00031 # include <config.h> 00032 #endif 00033 00034 #include <gtk/gtk.h> 00035 #include <glade/glade.h> 00036 #include <ctype.h> 00037 00038 #include "client.h" 00039 00040 #include "image.h" 00041 00042 #include "main.h" 00043 #include "gtk2proto.h" 00044 #include "metaserver.h" 00045 00046 static GtkWidget *add_character_window, *choose_char_window, 00047 *create_account_window, *login_window, *account_password_window; 00048 00049 /* These are in the login_window */ 00050 static GtkWidget *button_login, *button_create_account, 00051 *button_go_metaserver, *button_exit_client, 00052 *entry_account_name, 00053 *entry_account_password, *label_account_login_status; 00054 00055 /* These are in the create_account_window */ 00056 static GtkWidget *button_new_create_account, *button_new_cancel, 00057 *entry_new_account_name, 00058 *entry_new_account_password, *entry_new_confirm_password, 00059 *label_create_account_status; 00060 00061 /* These are in the choose_character window */ 00062 static GtkWidget *button_play_character, *button_create_character, 00063 *button_add_character, *button_return_login, *button_account_password, 00064 *treeview_choose_character; 00065 00066 /* These are in the new_character window */ 00067 static GtkWidget *entry_new_character_name, *new_character_window, 00068 *label_new_char_status, *button_create_new_char, 00069 *button_new_char_cancel; 00070 00071 /* These are in the account_password window */ 00072 static GtkWidget *entry_account_password_current, *entry_account_password_new, 00073 *entry_account_password_confirm, *button_account_password_confirm, 00074 *button_account_password_cancel, *label_account_password_status; 00075 00076 GtkListStore *character_store; 00077 00078 /* create_char.c also uses this */ 00079 char account_password[256]; 00080 00081 /* This enum just maps the columns in the list store to their position. 00082 */ 00083 enum {CHAR_IMAGE, CHAR_NAME, CHAR_CLASS, CHAR_RACE, CHAR_LEVEL, CHAR_PARTY, 00084 CHAR_MAP, CHAR_ICON}; 00085 #define CHAR_NUM_COLUMNS 8 00086 00087 /* These are in the add_character window */ 00088 static GtkWidget *button_do_add_character, 00089 *button_return_character_select, *entry_character_name, 00090 *entry_character_password, *label_add_status; 00091 00092 GtkTextBuffer *textbuf_motd, *textbuf_news, *textbuf_rules_account, 00093 *textbuf_rules_char; 00094 00095 /* These are used as offsets for num_text_views - we share the drawing code in 00096 * info.c if more textviews are added, note that NUM_TEXT_VIEWS in info.c 00097 * needs to be increased. 00098 */ 00099 #define TEXTVIEW_MOTD 0 00100 #define TEXTVIEW_NEWS 1 00101 #define TEXTVIEW_RULES_ACCOUNT 2 00102 #define TEXTVIEW_RULES_CHAR 3 00103 00104 Info_Pane login_pane[4]; 00105 00106 extern int num_text_views; 00107 00108 static int has_init=0; 00109 00116 void hide_all_login_windows(void) 00117 { 00118 extern GtkWidget *treeview_look; 00119 00120 if (has_init) { 00121 /* If we have not initialized, nothing to hide */ 00122 gtk_widget_hide(login_window); 00123 gtk_widget_hide(add_character_window); 00124 gtk_widget_hide(choose_char_window); 00125 gtk_widget_hide(create_account_window); 00126 gtk_widget_hide(new_character_window); 00127 gtk_widget_hide(account_password_window); 00128 create_character_window_hide(); /* create_char.c */ 00129 00130 /* If the player has started playing (this function being called from 00131 * AddMeSuccess), we want to make sure that the extended command entry 00132 * widget is not activated - we want normal command entry. Where this 00133 * shows up is if the player was playing before and uses a savebed - 00134 * now the last thing activated is that entry widget. 00135 */ 00136 gtk_widget_grab_focus(GTK_WIDGET(treeview_look)); 00137 } 00138 } 00139 00148 gboolean on_window_delete_event(GtkWidget *window, gpointer *user_data) { 00149 return TRUE; 00150 } 00151 00152 /***************************************************************************** 00153 * New character window functions 00154 *****************************************************************************/ 00155 00167 void create_new_character_failure(char *message) 00168 { 00169 GtkWidget *dialog; 00170 00171 dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, 00172 GTK_BUTTONS_OK, 00173 "Error: %s", message); 00174 gtk_dialog_run(GTK_DIALOG(dialog)); 00175 gtk_widget_destroy(dialog); 00176 00177 } 00178 00182 static void create_new_character(void) 00183 { 00184 const char *name; 00185 uint8 buf[MAX_BUF]; 00186 SockList sl; 00187 00188 SockList_Init(&sl, buf); 00189 00190 name = gtk_entry_get_text(GTK_ENTRY(entry_new_character_name)); 00191 00192 if (!name || *name == 0) { 00193 gtk_label_set_text(GTK_LABEL(label_new_char_status), 00194 "You must enter a character name."); 00195 return; 00196 } else { 00197 gtk_label_set_text(GTK_LABEL(label_new_char_status), ""); 00198 00199 SockList_AddString(&sl, "createplayer "); 00200 SockList_AddChar(&sl, strlen(name)); 00201 SockList_AddString(&sl, name); 00202 SockList_AddChar(&sl, strlen(account_password)); 00203 SockList_AddString(&sl, account_password); 00204 SockList_Send(&sl, csocket.fd); 00205 } 00206 } 00207 00213 void 00214 on_button_create_new_char_clicked(GtkButton *button, gpointer user_data) 00215 { 00216 create_new_character(); 00217 } 00218 00225 void on_entry_new_character_name(GtkEntry *entry, gpointer user_data) 00226 { 00227 create_new_character(); 00228 } 00229 00236 void 00237 on_button_new_char_cancel_clicked(GtkButton *button, gpointer user_data) 00238 { 00239 gtk_widget_hide(new_character_window); 00240 gtk_widget_show(choose_char_window); 00241 } 00242 00246 static void init_new_character_window(void) 00247 { 00248 GladeXML *xml_tree; 00249 00250 new_character_window = 00251 glade_xml_get_widget(dialog_xml, "new_character_window"); 00252 00253 gtk_window_set_transient_for( 00254 GTK_WINDOW(new_character_window), GTK_WINDOW(window_root)); 00255 00256 xml_tree = glade_get_widget_tree(GTK_WIDGET(new_character_window)); 00257 00258 button_create_new_char = 00259 glade_xml_get_widget(dialog_xml,"button_create_new_char"); 00260 button_new_char_cancel = 00261 glade_xml_get_widget(dialog_xml,"button_new_char_cancel"); 00262 entry_new_character_name = 00263 glade_xml_get_widget(dialog_xml,"entry_new_character_name"); 00264 label_new_char_status = 00265 glade_xml_get_widget(dialog_xml,"label_new_char_status"); 00266 00267 g_signal_connect((gpointer) new_character_window, "delete_event", 00268 G_CALLBACK(on_window_delete_event), NULL); 00269 g_signal_connect((gpointer) button_create_new_char, "clicked", 00270 G_CALLBACK(on_button_create_new_char_clicked), NULL); 00271 g_signal_connect((gpointer) button_new_char_cancel, "clicked", 00272 G_CALLBACK(on_button_new_char_cancel_clicked), NULL); 00273 g_signal_connect((gpointer) entry_new_character_name, "activate", 00274 G_CALLBACK(on_entry_new_character_name), NULL); 00275 } 00276 00277 /****************************************************************************** 00278 * add_character_window functions 00279 *****************************************************************************/ 00280 00287 static void add_character_to_account(const char *name, const char *password, int force) 00288 { 00289 SockList sl; 00290 uint8 buf[MAX_BUF]; 00291 00292 if (!name || !password || *name == 0 || *password == 0) { 00293 gtk_label_set_text(GTK_LABEL(label_add_status), 00294 "You must enter both a name and password!"); 00295 } else { 00296 gtk_label_set_text(GTK_LABEL(label_add_status), ""); 00297 00298 SockList_Init(&sl, buf); 00299 SockList_AddString(&sl, "accountaddplayer "); 00300 SockList_AddChar(&sl, force); 00301 SockList_AddChar(&sl, strlen(name)); 00302 SockList_AddString(&sl, name); 00303 SockList_AddChar(&sl, strlen(password)); 00304 SockList_AddString(&sl, password); 00305 SockList_Send(&sl, csocket.fd); 00306 } 00307 } 00308 00320 void account_add_character_failure(char *message) 00321 { 00322 char *cp; 00323 int retry; 00324 00325 retry = atoi(message); 00326 cp = strchr(message,' '); 00327 if (cp) { 00328 cp++; 00329 } else 00330 cp=message; 00331 00332 if (!retry) { 00333 gtk_label_set_text(GTK_LABEL(label_add_status), cp); 00334 } else { 00335 /* In this case, we can retry it and it should work if we set force. 00336 * So bring up a dialog, as the user what to do - if they enter yes, 00337 * we use force. If not, we clear the entry fields and just continue 00338 * onward. 00339 */ 00340 GtkWidget *dialog; 00341 int result; 00342 const char *name, *password; 00343 00344 /* Bring up a dialog window */ 00345 dialog = 00346 gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, 00347 GTK_BUTTONS_YES_NO, "%s\n%s", cp, "Apply anyways?"); 00348 result = gtk_dialog_run(GTK_DIALOG(dialog)); 00349 gtk_widget_destroy(dialog); 00350 00351 if (result == GTK_RESPONSE_YES ) { 00352 name = gtk_entry_get_text(GTK_ENTRY(entry_character_name)); 00353 password = gtk_entry_get_text(GTK_ENTRY(entry_character_password)); 00354 add_character_to_account(name, password, 1); 00355 } else { 00356 gtk_entry_set_text(GTK_ENTRY(entry_character_name), ""); 00357 gtk_entry_set_text(GTK_ENTRY(entry_character_password), ""); 00358 gtk_widget_grab_focus(entry_character_name); 00359 } 00360 } 00361 } 00362 00370 void 00371 on_button_do_add_character_clicked(GtkButton *button, gpointer user_data) 00372 { 00373 add_character_to_account( 00374 gtk_entry_get_text(GTK_ENTRY(entry_character_name)), 00375 gtk_entry_get_text(GTK_ENTRY(entry_character_password)), 0); 00376 } 00377 00385 void 00386 on_button_return_character_select_clicked(GtkButton *button, gpointer user_data) 00387 { 00388 gtk_widget_hide(add_character_window); 00389 gtk_widget_show(choose_char_window); 00390 } 00391 00400 void on_entry_character(GtkEntry *entry, gpointer user_data) { 00401 const char *name, *password; 00402 00403 name = gtk_entry_get_text(GTK_ENTRY(entry_character_name)); 00404 password = gtk_entry_get_text(GTK_ENTRY(entry_character_password)); 00405 00406 if (name && name[0] && password && password[0]) { 00407 add_character_to_account(name, password, 0); 00408 } else { 00409 const char *cp; 00410 00411 /* First case - this widget is empty - do nothing */ 00412 cp = gtk_entry_get_text(entry); 00413 if (!cp || !cp[0]) return; 00414 00415 /* In this case, this widget is not empty - means the other one is. 00416 */ 00417 if (entry == GTK_ENTRY(entry_character_name)) 00418 gtk_widget_grab_focus(entry_character_password); 00419 else 00420 gtk_widget_grab_focus(entry_character_name); 00421 } 00422 } 00423 00427 static void init_add_character_window(void) { 00428 GladeXML *xml_tree; 00429 00430 add_character_window = 00431 glade_xml_get_widget(dialog_xml, "add_character_window"); 00432 00433 gtk_window_set_transient_for( 00434 GTK_WINDOW(add_character_window), GTK_WINDOW(window_root)); 00435 00436 xml_tree = glade_get_widget_tree(GTK_WIDGET(add_character_window)); 00437 00438 button_do_add_character = 00439 glade_xml_get_widget(dialog_xml,"button_do_add_character"); 00440 button_return_character_select = 00441 glade_xml_get_widget(dialog_xml,"button_return_character_select"); 00442 entry_character_name = 00443 glade_xml_get_widget(dialog_xml,"entry_character_name"); 00444 entry_character_password = 00445 glade_xml_get_widget(dialog_xml,"entry_character_password"); 00446 label_add_status = 00447 glade_xml_get_widget(dialog_xml,"label_add_status"); 00448 00449 g_signal_connect((gpointer) add_character_window, "delete_event", 00450 G_CALLBACK(on_window_delete_event), NULL); 00451 g_signal_connect((gpointer) button_do_add_character, "clicked", 00452 G_CALLBACK(on_button_do_add_character_clicked), NULL); 00453 g_signal_connect((gpointer) button_return_character_select, "clicked", 00454 G_CALLBACK(on_button_return_character_select_clicked), NULL); 00455 g_signal_connect((gpointer) entry_character_name, "activate", 00456 G_CALLBACK(on_entry_character), NULL); 00457 g_signal_connect((gpointer) entry_character_password, "activate", 00458 G_CALLBACK(on_entry_character), NULL); 00459 } 00460 00461 /***************************************************************************** 00462 * choose_char_window 00463 ****************************************************************************/ 00464 00471 void choose_character_init(void) 00472 { 00473 gtk_widget_hide(login_window); 00474 gtk_widget_hide(add_character_window); 00475 gtk_widget_hide(create_account_window); 00476 gtk_widget_show(choose_char_window); 00477 00478 /* Store any old/stale entries */ 00479 gtk_list_store_clear(character_store); 00480 } 00481 00489 void choose_char_window_show() 00490 { 00491 gtk_widget_show(choose_char_window); 00492 } 00493 00494 00499 static void play_character(const char *name) 00500 { 00501 SockList sl; 00502 uint8 buf[MAX_BUF]; 00503 00504 SockList_Init(&sl, buf); 00505 SockList_AddString(&sl, "accountplay "); 00506 SockList_AddString(&sl, name); 00507 SockList_Send(&sl, csocket.fd); 00508 } 00509 00516 void 00517 on_button_play_character_clicked(GtkButton *button, gpointer user_data) 00518 { 00519 GtkTreeSelection *selected; 00520 GtkTreeModel *model; 00521 GtkTreeIter iter; 00522 char *name; 00523 00524 selected = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_choose_character)); 00525 00526 if (gtk_tree_selection_get_selected(selected, &model, &iter)) { 00527 gtk_tree_model_get(model, &iter, CHAR_NAME, &name, -1); 00528 00529 play_character(name); 00530 } 00531 } 00532 00538 void 00539 on_button_create_character_clicked(GtkButton *button, gpointer user_data) 00540 { 00541 gtk_widget_hide(choose_char_window); 00542 if (serverloginmethod >= 2) { 00543 create_character_window_show(); 00544 } else { 00545 gtk_widget_show(new_character_window); 00546 gtk_entry_set_text(GTK_ENTRY(entry_new_character_name), ""); 00547 } 00548 } 00549 00556 void 00557 on_button_add_character_clicked(GtkButton *button, gpointer user_data) 00558 { 00559 gtk_widget_hide(choose_char_window); 00560 gtk_widget_show(add_character_window); 00561 gtk_entry_set_text(GTK_ENTRY(entry_character_name), ""); 00562 gtk_entry_set_text(GTK_ENTRY(entry_character_password), ""); 00563 gtk_widget_grab_focus(entry_character_name); 00564 } 00565 00572 void 00573 on_button_return_login_clicked(GtkButton *button, gpointer user_data) 00574 { 00575 gtk_widget_hide(choose_char_window); 00576 gtk_widget_show(login_window); 00577 } 00578 00585 void 00586 on_button_account_password_clicked(GtkButton *button, gpointer user_data) 00587 { 00588 gtk_widget_hide(choose_char_window); 00589 gtk_widget_show(account_password_window); 00590 /* reset previous values */ 00591 gtk_entry_set_text(GTK_ENTRY(entry_account_password_current), ""); 00592 gtk_entry_set_text(GTK_ENTRY(entry_account_password_new), ""); 00593 gtk_entry_set_text(GTK_ENTRY(entry_account_password_confirm), ""); 00594 } 00595 00610 void update_character_choose(const char *name, const char *class, 00611 const char *race, const char *face, 00612 const char *party, const char *map, 00613 int level, int faceno) 00614 { 00615 GtkTreeIter iter; 00616 00617 gtk_list_store_append(character_store, &iter); 00618 00619 /* If this pixmap matches pixmap[0], it means we are caching images and 00620 * this image hasn't been set up. It looks better in this case to just 00621 * leave that area of the window blank vs drawing a question mark there. 00622 */ 00623 if (pixmaps[faceno] == pixmaps[0]) { 00624 gtk_list_store_set(character_store, &iter, 00625 CHAR_NAME, name, 00626 CHAR_CLASS, class, 00627 CHAR_RACE, race, 00628 CHAR_IMAGE, face, 00629 CHAR_PARTY, party, 00630 CHAR_MAP, map, 00631 CHAR_LEVEL, level, 00632 -1); 00633 } else { 00634 gtk_list_store_set(character_store, &iter, 00635 CHAR_ICON, pixmaps[faceno]->icon_image, 00636 CHAR_NAME, name, 00637 CHAR_CLASS, class, 00638 CHAR_RACE, race, 00639 CHAR_IMAGE, face, 00640 CHAR_PARTY, party, 00641 CHAR_MAP, map, 00642 CHAR_LEVEL, level, 00643 -1); 00644 } 00645 } 00646 00657 void on_treeview_choose_character_activated(GtkTreeView *treeview, 00658 GtkTreePath *path, 00659 GtkTreeViewColumn *column, 00660 gpointer user_data) 00661 { 00662 GtkTreeIter iter; 00663 GtkTreeModel *model; 00664 char *name; 00665 00666 model = gtk_tree_view_get_model(treeview); 00667 if (gtk_tree_model_get_iter(model, &iter, path)) { 00668 gtk_tree_model_get(model, &iter, CHAR_NAME, &name, -1); 00669 00670 if (!name) { 00671 LOG(LOG_ERROR,"account.c::on_treeview_choose_character_activated", "unable to get character name"); 00672 return; 00673 } 00674 play_character(name); 00675 } 00676 } 00677 00681 static void init_choose_char_window(void) { 00682 00683 GladeXML *xml_tree; 00684 GtkTextIter end; 00685 GtkCellRenderer *renderer; 00686 GtkTreeViewColumn *column; 00687 00688 choose_char_window = 00689 glade_xml_get_widget(dialog_xml, "choose_character_window"); 00690 00691 gtk_window_set_transient_for( 00692 GTK_WINDOW(choose_char_window), GTK_WINDOW(window_root)); 00693 00694 xml_tree = glade_get_widget_tree(GTK_WIDGET(choose_char_window)); 00695 00696 button_play_character = 00697 glade_xml_get_widget(dialog_xml,"button_play_character"); 00698 button_create_character = 00699 glade_xml_get_widget(dialog_xml,"button_create_character"); 00700 button_add_character = 00701 glade_xml_get_widget(dialog_xml,"button_add_character"); 00702 button_return_login = 00703 glade_xml_get_widget(dialog_xml,"button_return_login"); 00704 button_account_password = 00705 glade_xml_get_widget(dialog_xml,"button_account_password"); 00706 login_pane[TEXTVIEW_RULES_CHAR].textview = 00707 glade_xml_get_widget(dialog_xml,"textview_rules_char"); 00708 00709 textbuf_rules_char = 00710 gtk_text_view_get_buffer( 00711 GTK_TEXT_VIEW(login_pane[TEXTVIEW_RULES_CHAR].textview)); 00712 00713 treeview_choose_character = 00714 glade_xml_get_widget(dialog_xml,"treeview_choose_character"); 00715 00716 add_tags_to_textbuffer( 00717 &login_pane[TEXTVIEW_RULES_CHAR], textbuf_rules_char); 00718 add_style_to_textbuffer(&login_pane[TEXTVIEW_RULES_CHAR], NULL); 00719 gtk_text_buffer_get_end_iter( 00720 login_pane[TEXTVIEW_RULES_CHAR].textbuffer, &end); 00721 login_pane[TEXTVIEW_RULES_CHAR].textmark = 00722 gtk_text_buffer_create_mark( 00723 login_pane[TEXTVIEW_RULES_CHAR].textbuffer, NULL, &end, FALSE); 00724 00725 g_signal_connect((gpointer) choose_char_window, "delete_event", 00726 G_CALLBACK(on_window_delete_event), NULL); 00727 g_signal_connect((gpointer) button_play_character, "clicked", 00728 G_CALLBACK(on_button_play_character_clicked), NULL); 00729 g_signal_connect((gpointer) button_create_character, "clicked", 00730 G_CALLBACK(on_button_create_character_clicked), NULL); 00731 g_signal_connect((gpointer) button_add_character, "clicked", 00732 G_CALLBACK(on_button_add_character_clicked), NULL); 00733 g_signal_connect((gpointer) button_return_login, "clicked", 00734 G_CALLBACK(on_button_return_login_clicked), NULL); 00735 g_signal_connect((gpointer) button_account_password, "clicked", 00736 G_CALLBACK(on_button_account_password_clicked), NULL); 00737 g_signal_connect((gpointer) treeview_choose_character, "row_activated", 00738 G_CALLBACK(on_treeview_choose_character_activated), NULL); 00739 00740 character_store = gtk_list_store_new(CHAR_NUM_COLUMNS, 00741 G_TYPE_STRING, G_TYPE_STRING, 00742 G_TYPE_STRING, G_TYPE_STRING, 00743 G_TYPE_INT, G_TYPE_STRING, 00744 G_TYPE_STRING, G_TYPE_OBJECT); 00745 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_choose_character), 00746 GTK_TREE_MODEL(character_store)); 00747 00748 renderer = gtk_cell_renderer_pixbuf_new(); 00749 column = gtk_tree_view_column_new_with_attributes("?", renderer, 00750 "pixbuf", CHAR_ICON, 00751 NULL); 00752 00753 gtk_tree_view_column_set_min_width(column, image_size); 00754 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00755 00756 renderer = gtk_cell_renderer_text_new(); 00757 column = gtk_tree_view_column_new_with_attributes("Character Name", renderer, 00758 "text", CHAR_NAME, NULL); 00759 gtk_tree_view_column_set_sort_column_id(column, CHAR_NAME); 00760 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00761 00762 renderer = gtk_cell_renderer_text_new(); 00763 column = gtk_tree_view_column_new_with_attributes("Class", renderer, 00764 "text", CHAR_CLASS, NULL); 00765 gtk_tree_view_column_set_sort_column_id(column, CHAR_CLASS); 00766 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00767 00768 renderer = gtk_cell_renderer_text_new(); 00769 column = gtk_tree_view_column_new_with_attributes("Race", renderer, 00770 "text", CHAR_RACE, NULL); 00771 gtk_tree_view_column_set_sort_column_id(column, CHAR_RACE); 00772 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00773 00774 renderer = gtk_cell_renderer_text_new(); 00775 column = gtk_tree_view_column_new_with_attributes("Level", renderer, 00776 "text", CHAR_LEVEL, NULL); 00777 gtk_tree_view_column_set_sort_column_id(column, CHAR_LEVEL); 00778 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00779 00780 renderer = gtk_cell_renderer_text_new(); 00781 column = gtk_tree_view_column_new_with_attributes("Party", renderer, 00782 "text", CHAR_PARTY, NULL); 00783 gtk_tree_view_column_set_sort_column_id(column, CHAR_PARTY); 00784 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00785 00786 renderer = gtk_cell_renderer_text_new(); 00787 column = gtk_tree_view_column_new_with_attributes("Map", renderer, 00788 "text", CHAR_MAP, NULL); 00789 gtk_tree_view_column_set_sort_column_id(column, CHAR_MAP); 00790 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_choose_character), column); 00791 } 00792 00793 /****************************************************************************** 00794 * create_account_window 00795 ******************************************************************************/ 00796 00802 void account_creation_failure(char *message) 00803 { 00804 gtk_label_set_text(GTK_LABEL(label_create_account_status), message); 00805 } 00806 00819 static void do_account_create(const char *name, const char *p1, const char *p2) 00820 { 00821 SockList sl; 00822 uint8 buf[MAX_BUF]; 00823 00824 if (strcmp(p1, p2)) { 00825 gtk_label_set_text(GTK_LABEL(label_create_account_status), 00826 "The passwords you entered do not match!"); 00827 return; 00828 } else { 00829 gtk_label_set_text(GTK_LABEL(label_create_account_status), ""); 00830 SockList_Init(&sl, buf); 00831 SockList_AddString(&sl, "accountnew "); 00832 SockList_AddChar(&sl, strlen(name)); 00833 SockList_AddString(&sl, name); 00834 SockList_AddChar(&sl, strlen(p1)); 00835 SockList_AddString(&sl, p1); 00836 SockList_Send(&sl, csocket.fd); 00837 /* Store password away for new character creation */ 00838 snprintf(account_password, sizeof(account_password), "%s", p1); 00839 } 00840 } 00841 00848 void 00849 on_button_new_create_account_clicked(GtkButton *button, gpointer user_data) 00850 { 00851 const char *password1, *password2, *name; 00852 00853 password1 = gtk_entry_get_text(GTK_ENTRY(entry_new_account_password)); 00854 password2 = gtk_entry_get_text(GTK_ENTRY(entry_new_confirm_password)); 00855 name = gtk_entry_get_text(GTK_ENTRY(entry_new_account_name)); 00856 00857 if (name && name[0] && password1 && password1[0] && password2 && password2[0]) { 00858 do_account_create(name, password1, password2); 00859 } else { 00860 gtk_label_set_text(GTK_LABEL(label_create_account_status), 00861 "You must fill in all three entries!"); 00862 } 00863 } 00864 00870 void 00871 on_button_new_cancel_clicked(GtkButton *button, gpointer user_data) 00872 { 00873 gtk_widget_hide(create_account_window); 00874 gtk_widget_show(login_window); 00875 } 00876 00886 void 00887 on_entry_new_account(GtkEntry *entry, gpointer user_data) { 00888 00889 const char *password1, *password2, *name, *cp; 00890 00891 password1 = gtk_entry_get_text(GTK_ENTRY(entry_new_account_password)); 00892 password2 = gtk_entry_get_text(GTK_ENTRY(entry_new_confirm_password)); 00893 name = gtk_entry_get_text(GTK_ENTRY(entry_new_account_name)); 00894 if (name && name[0] && password1 && password1[0] && password2 && password2[0]) { 00895 do_account_create(name, password1, password2); 00896 } else { 00897 /* In this case, one, or more, of the fields is blank. If there were 00898 * more than 3 widgets, I might but them into an array to make cycling 00899 * easier 00900 */ 00901 00902 /* First case - if the currently active one is blank, no reason to 00903 * move onward. 00904 */ 00905 cp = gtk_entry_get_text(entry); 00906 if (!cp || !cp[0]) return; 00907 00908 /* I'm not sure if it would make more sense to advance to the first 00909 * NULL entry - but in that case, the pointer may hop in non intuitive 00910 * ways - in this case, the user may just need to hit return a few 00911 * times - MSW 2010/03/29 00912 */ 00913 if (entry == GTK_ENTRY(entry_new_account_name)) 00914 gtk_widget_grab_focus(entry_new_account_password); 00915 else if (entry == GTK_ENTRY(entry_new_account_password)) 00916 gtk_widget_grab_focus(entry_new_confirm_password); 00917 else if (entry == GTK_ENTRY(entry_new_confirm_password)) 00918 gtk_widget_grab_focus(entry_new_account_name); 00919 } 00920 } 00921 00926 static void init_create_account_window(void) 00927 { 00928 GladeXML *xml_tree; 00929 GtkTextIter end; 00930 00931 create_account_window = 00932 glade_xml_get_widget(dialog_xml, "create_account_window"); 00933 00934 gtk_window_set_transient_for( 00935 GTK_WINDOW(create_account_window), GTK_WINDOW(window_root)); 00936 00937 xml_tree = glade_get_widget_tree(GTK_WIDGET(create_account_window)); 00938 00939 button_new_create_account = 00940 glade_xml_get_widget(dialog_xml,"button_new_create_account"); 00941 button_new_cancel = 00942 glade_xml_get_widget(dialog_xml,"button_new_cancel"); 00943 login_pane[TEXTVIEW_RULES_ACCOUNT].textview = 00944 glade_xml_get_widget(dialog_xml,"textview_rules_account"); 00945 00946 textbuf_rules_account = 00947 gtk_text_view_get_buffer( 00948 GTK_TEXT_VIEW(login_pane[TEXTVIEW_RULES_ACCOUNT].textview )); 00949 00950 entry_new_account_name = 00951 glade_xml_get_widget(dialog_xml,"entry_new_account_name"); 00952 entry_new_account_password = 00953 glade_xml_get_widget(dialog_xml,"entry_new_account_password"); 00954 entry_new_confirm_password = 00955 glade_xml_get_widget(dialog_xml,"entry_new_confirm_password"); 00956 label_create_account_status = 00957 glade_xml_get_widget(dialog_xml,"label_create_account_status"); 00958 00959 add_tags_to_textbuffer( 00960 &login_pane[TEXTVIEW_RULES_ACCOUNT], textbuf_rules_account); 00961 add_style_to_textbuffer(&login_pane[TEXTVIEW_RULES_ACCOUNT], NULL); 00962 gtk_text_buffer_get_end_iter( 00963 login_pane[TEXTVIEW_RULES_ACCOUNT].textbuffer, &end); 00964 login_pane[TEXTVIEW_RULES_ACCOUNT].textmark = 00965 gtk_text_buffer_create_mark( 00966 login_pane[TEXTVIEW_RULES_ACCOUNT].textbuffer, NULL, &end, FALSE); 00967 00968 g_signal_connect((gpointer) create_account_window, "delete_event", 00969 G_CALLBACK(on_window_delete_event), NULL); 00970 g_signal_connect((gpointer) button_new_create_account, "clicked", 00971 G_CALLBACK(on_button_new_create_account_clicked), NULL); 00972 g_signal_connect((gpointer) button_new_cancel, "clicked", 00973 G_CALLBACK(on_button_new_cancel_clicked), NULL); 00974 g_signal_connect((gpointer) entry_new_account_name, "activate", 00975 G_CALLBACK(on_entry_new_account), NULL); 00976 g_signal_connect((gpointer) entry_new_account_password, "activate", 00977 G_CALLBACK(on_entry_new_account), NULL); 00978 g_signal_connect((gpointer) entry_new_confirm_password, "activate", 00979 G_CALLBACK(on_entry_new_account), NULL); 00980 } 00981 00982 /***************************************************************************** 00983 * login_window 00984 *****************************************************************************/ 00985 00991 void account_login_failure(char *message) 00992 { 00993 gtk_label_set_text(GTK_LABEL(label_account_login_status), message); 00994 } 00995 01002 void 01003 on_button_create_account_clicked(GtkButton *button, gpointer user_data) 01004 { 01005 gtk_widget_hide(login_window); 01006 gtk_label_set_text(GTK_LABEL(label_create_account_status), ""); 01007 gtk_entry_set_text(GTK_ENTRY(entry_new_account_name), ""); 01008 gtk_entry_set_text(GTK_ENTRY(entry_new_account_password), ""); 01009 gtk_entry_set_text(GTK_ENTRY(entry_new_confirm_password), ""); 01010 gtk_widget_show(create_account_window); 01011 } 01012 01020 void 01021 on_button_go_metaserver_clicked(GtkButton *button, gpointer user_data) 01022 { 01023 close_server_connection(); 01024 01025 if (csocket_fd) { 01026 gdk_input_remove(csocket_fd); 01027 csocket_fd=0; 01028 gtk_main_quit(); 01029 } 01030 } 01031 01037 void 01038 on_button_exit_client_clicked(GtkButton *button, gpointer user_data) 01039 { 01040 #ifdef WIN32 01041 script_killall(); 01042 #endif 01043 exit(0); 01044 } 01045 01053 static void do_account_login(const char *name, const char *password) 01054 { 01055 SockList sl; 01056 uint8 buf[MAX_BUF]; 01057 01058 if (!name || !password || *name == 0 || *password == 0) { 01059 gtk_label_set_text(GTK_LABEL(label_account_login_status), 01060 "You must enter both a name and password!"); 01061 } else { 01062 gtk_label_set_text(GTK_LABEL(label_account_login_status), ""); 01063 01064 SockList_Init(&sl, buf); 01065 SockList_AddString(&sl, "accountlogin "); 01066 SockList_AddChar(&sl, strlen(name)); 01067 SockList_AddString(&sl, name); 01068 SockList_AddChar(&sl, strlen(password)); 01069 SockList_AddString(&sl, password); 01070 SockList_Send(&sl, csocket.fd); 01071 /* Store password away for new character creation */ 01072 snprintf(account_password, sizeof(account_password), "%s", password); 01073 } 01074 } 01075 01081 void 01082 on_button_login_clicked(GtkButton *button, gpointer user_data) 01083 { 01084 do_account_login(gtk_entry_get_text(GTK_ENTRY(entry_account_name)), 01085 gtk_entry_get_text(GTK_ENTRY(entry_account_password))); 01086 } 01087 01094 void 01095 on_entry_account_name_activate(GtkEntry *entry, gpointer user_data) { 01096 const char *password; 01097 01098 password = gtk_entry_get_text(GTK_ENTRY(entry_account_password)); 01099 01100 if (!password || *password == 0) { 01101 gtk_widget_grab_focus(entry_account_password); 01102 } else { 01103 do_account_login(gtk_entry_get_text(GTK_ENTRY(entry_account_name)), password); 01104 } 01105 } 01106 01113 void 01114 on_entry_account_password_activate(GtkEntry *entry, gpointer user_data) { 01115 const char *name; 01116 01117 name = gtk_entry_get_text(GTK_ENTRY(entry_account_name)); 01118 01119 if (!name || *name == 0) { 01120 gtk_widget_grab_focus(entry_account_name); 01121 } else { 01122 do_account_login(name, gtk_entry_get_text(GTK_ENTRY(entry_account_password))); 01123 } 01124 } 01125 01130 static void init_login_window(void) 01131 { 01132 GladeXML *xml_tree; 01133 GtkTextIter end; 01134 01135 login_window = glade_xml_get_widget(dialog_xml, "login_window"); 01136 01137 if (!login_window) { 01138 error_dialog("Out of date dialog.glade", "Did you run 'make install'?"); 01139 exit(1); 01140 } 01141 01142 gtk_window_set_transient_for( 01143 GTK_WINDOW(login_window), GTK_WINDOW(window_root)); 01144 01145 xml_tree = glade_get_widget_tree(GTK_WIDGET(login_window)); 01146 01147 button_login = 01148 glade_xml_get_widget(dialog_xml,"button_login"); 01149 button_create_account = 01150 glade_xml_get_widget(dialog_xml,"button_create_account"); 01151 button_go_metaserver = 01152 glade_xml_get_widget(dialog_xml,"button_go_metaserver"); 01153 button_exit_client = 01154 glade_xml_get_widget(dialog_xml,"button_exit_client"); 01155 label_account_login_status = 01156 glade_xml_get_widget(dialog_xml,"label_account_login_status"); 01157 login_pane[TEXTVIEW_MOTD].textview = 01158 glade_xml_get_widget(dialog_xml,"textview_motd"); 01159 01160 textbuf_motd = 01161 gtk_text_view_get_buffer( 01162 GTK_TEXT_VIEW(login_pane[TEXTVIEW_MOTD].textview)); 01163 01164 add_tags_to_textbuffer(&login_pane[TEXTVIEW_MOTD], textbuf_motd); 01165 add_style_to_textbuffer(&login_pane[TEXTVIEW_MOTD], NULL); 01166 gtk_text_buffer_get_end_iter(login_pane[TEXTVIEW_MOTD].textbuffer, &end); 01167 login_pane[TEXTVIEW_MOTD].textmark = 01168 gtk_text_buffer_create_mark( 01169 login_pane[TEXTVIEW_MOTD].textbuffer, NULL, &end, FALSE); 01170 01171 login_pane[TEXTVIEW_NEWS].textview = 01172 glade_xml_get_widget(dialog_xml,"textview_news"); 01173 01174 textbuf_news = 01175 gtk_text_view_get_buffer( 01176 GTK_TEXT_VIEW(login_pane[TEXTVIEW_NEWS].textview)); 01177 01178 add_tags_to_textbuffer(&login_pane[TEXTVIEW_NEWS], textbuf_news); 01179 add_style_to_textbuffer(&login_pane[TEXTVIEW_NEWS], NULL); 01180 gtk_text_buffer_get_end_iter(login_pane[TEXTVIEW_NEWS].textbuffer, &end); 01181 login_pane[TEXTVIEW_NEWS].textmark = 01182 gtk_text_buffer_create_mark( 01183 login_pane[TEXTVIEW_NEWS].textbuffer, NULL, &end, FALSE); 01184 01185 entry_account_name = 01186 glade_xml_get_widget(dialog_xml,"entry_account_name"); 01187 entry_account_password = 01188 glade_xml_get_widget(dialog_xml,"entry_account_password"); 01189 01190 g_signal_connect((gpointer) login_window, "delete_event", 01191 G_CALLBACK(on_window_delete_event), NULL); 01192 g_signal_connect((gpointer) entry_account_name, "activate", 01193 G_CALLBACK(on_entry_account_name_activate), NULL); 01194 g_signal_connect((gpointer) entry_account_password, "activate", 01195 G_CALLBACK(on_entry_account_password_activate), NULL); 01196 g_signal_connect((gpointer) button_login, "clicked", 01197 G_CALLBACK(on_button_login_clicked), NULL); 01198 g_signal_connect((gpointer) button_create_account, "clicked", 01199 G_CALLBACK(on_button_create_account_clicked), NULL); 01200 g_signal_connect((gpointer) button_go_metaserver, "clicked", 01201 G_CALLBACK(on_button_go_metaserver_clicked), NULL); 01202 g_signal_connect((gpointer) button_exit_client, "clicked", 01203 G_CALLBACK(on_button_exit_client_clicked), NULL); 01204 } 01205 01206 /***************************************************************************** 01207 * Account password change 01208 ****************************************************************************/ 01209 01222 static void do_account_change(const char *old, const char *p1, const char *p2) 01223 { 01224 SockList sl; 01225 uint8 buf[MAX_BUF]; 01226 01227 if (strcmp(p1, p2)) { 01228 gtk_label_set_text(GTK_LABEL(label_account_password_status), 01229 "The passwords you entered do not match!"); 01230 return; 01231 } else { 01232 gtk_label_set_text(GTK_LABEL(label_account_password_status), ""); 01233 SockList_Init(&sl, buf); 01234 SockList_AddString(&sl, "accountpw "); 01235 SockList_AddChar(&sl, strlen(old)); 01236 SockList_AddString(&sl, old); 01237 SockList_AddChar(&sl, strlen(p1)); 01238 SockList_AddString(&sl, p1); 01239 SockList_Send(&sl, csocket.fd); 01240 /* Store password away for new character creation */ 01241 snprintf(account_password, sizeof(account_password), "%s", p1); 01242 } 01243 } 01244 01251 void 01252 on_button_account_password_cancel_clicked(GtkButton *button, gpointer user_data) 01253 { 01254 gtk_widget_hide(account_password_window); 01255 gtk_widget_show(choose_char_window); 01256 } 01257 01263 void 01264 on_button_account_password_confirm_clicked(GtkButton *button, gpointer user_data) 01265 { 01266 do_account_change(gtk_entry_get_text(GTK_ENTRY(entry_account_password_current)), 01267 gtk_entry_get_text(GTK_ENTRY(entry_account_password_new)), 01268 gtk_entry_get_text(GTK_ENTRY(entry_account_password_confirm))); 01269 } 01270 01280 void 01281 on_entry_account_password(GtkEntry *entry, gpointer user_data) { 01282 01283 const char *old, *password1, *password2, *cp; 01284 01285 old = gtk_entry_get_text(GTK_ENTRY(entry_account_password_current)); 01286 password1 = gtk_entry_get_text(GTK_ENTRY(entry_account_password_new)); 01287 password2 = gtk_entry_get_text(GTK_ENTRY(entry_account_password_confirm)); 01288 if (old && old[0] && password1 && password1[0] && password2 && password2[0]) { 01289 do_account_change(old, password1, password2); 01290 } else { 01291 /* In this case, one, or more, of the fields is blank. If there were 01292 * more than 3 widgets, I might but them into an array to make cycling 01293 * easier 01294 */ 01295 01296 /* First case - if the currently active one is blank, no reason to 01297 * move onward. 01298 */ 01299 cp = gtk_entry_get_text(entry); 01300 if (!cp || !cp[0]) return; 01301 01302 if (entry == GTK_ENTRY(entry_account_password_current)) 01303 gtk_widget_grab_focus(entry_account_password_new); 01304 else if (entry == GTK_ENTRY(entry_account_password_new)) 01305 gtk_widget_grab_focus(entry_account_password_confirm); 01306 else if (entry == GTK_ENTRY(entry_account_password_confirm)) 01307 gtk_widget_grab_focus(entry_account_password_current); 01308 } 01309 } 01310 01311 void account_change_password_failure(char *message) { 01312 gtk_label_set_text(GTK_LABEL(label_account_password_status), message); 01313 } 01314 01319 static void init_account_password_window(void) 01320 { 01321 GladeXML *xml_tree; 01322 GtkTextIter end; 01323 01324 account_password_window = 01325 glade_xml_get_widget(dialog_xml, "account_password_window"); 01326 01327 gtk_window_set_transient_for( 01328 GTK_WINDOW(account_password_window), GTK_WINDOW(window_root)); 01329 01330 xml_tree = glade_get_widget_tree(GTK_WIDGET(account_password_window)); 01331 01332 button_account_password_confirm = 01333 glade_xml_get_widget(dialog_xml,"button_account_password_confirm"); 01334 button_account_password_cancel = 01335 glade_xml_get_widget(dialog_xml,"button_account_password_cancel"); 01336 01337 entry_account_password_current = 01338 glade_xml_get_widget(dialog_xml,"entry_account_password_current"); 01339 entry_account_password_new = 01340 glade_xml_get_widget(dialog_xml,"entry_account_password_new"); 01341 entry_account_password_confirm = 01342 glade_xml_get_widget(dialog_xml,"entry_account_password_confirm"); 01343 label_account_password_status = 01344 glade_xml_get_widget(dialog_xml,"label_account_password_status"); 01345 01346 g_signal_connect((gpointer) account_password_window, "delete_event", 01347 G_CALLBACK(on_window_delete_event), NULL); 01348 g_signal_connect((gpointer) button_account_password_confirm, "clicked", 01349 G_CALLBACK(on_button_account_password_confirm_clicked), NULL); 01350 g_signal_connect((gpointer) button_account_password_cancel, "clicked", 01351 G_CALLBACK(on_button_account_password_cancel_clicked), NULL); 01352 g_signal_connect((gpointer) entry_account_password_current, "activate", 01353 G_CALLBACK(on_entry_account_password), NULL); 01354 g_signal_connect((gpointer) entry_account_password_new, "activate", 01355 G_CALLBACK(on_entry_account_password), NULL); 01356 g_signal_connect((gpointer) entry_account_password_confirm, "activate", 01357 G_CALLBACK(on_entry_account_password), NULL); 01358 } 01359 01360 01361 /***************************************************************************** 01362 * Common/generic functions 01363 ****************************************************************************/ 01364 01372 void update_login_info(int type) 01373 { 01374 if (!has_init) return; 01375 01376 /* In all cases, we clear the buffer, and if we have data, then set it to 01377 * that data. This routine could be smarter an 01378 */ 01379 if (type == INFO_NEWS) { 01380 gtk_text_buffer_set_text(textbuf_news, "", 0); 01381 if (news) { 01382 /* the format of the news entry is special - there are a series of 01383 * %entries, and they are in reverse older (newest last) we want 01384 * to get rid of the %, make them more visible (convert them to 01385 * bold) and reverse the order. 01386 */ 01387 char *mynews, *cp, *el, big_buf[BIG_BUF], *cp1; 01388 01389 mynews = strdup(news); 01390 /* We basically work from the end of the string going towards the 01391 * start looking for % characters. If we find one, we have to 01392 * make sure it is at the start of the line or start of the buffer 01393 */ 01394 for (cp = mynews + strlen(mynews); cp > mynews; cp--) { 01395 if (*cp == '%' && (*(cp-1) == '\n' || cp == mynews)) { 01396 /* Find the end of the line */ 01397 el = strchr(cp, '\n'); 01398 /* null out the newline, put el one char beyond it */ 01399 if (el) { 01400 *el=0; 01401 el++; 01402 } 01403 /* There isn't a clear standard - % news may be valid, as 01404 * might be %news. If % news is used, it looks better to 01405 * get rid of that leading space. 01406 */ 01407 cp1 = cp+1; 01408 while (isspace(*cp1)) cp1++; 01409 01410 /* since we've null out the newline, this snprintf will 01411 * only get the % line and that is it. Mark it up 01412 */ 01413 snprintf(big_buf, BIG_BUF, "[b]%s[/b]", cp1); 01414 add_marked_text_to_pane(&login_pane[TEXTVIEW_NEWS], big_buf, 0, 0, 0); 01415 /* Now we draw the text that goes with it, if it exists */ 01416 if (el) 01417 add_marked_text_to_pane(&login_pane[TEXTVIEW_NEWS], el, 0, 0, 0); 01418 01419 /* Now we wipe the % out. In this way, the news buffer is 01420 * shorter, so when it draws the ext, there will just be 01421 * that between the % and the one we just wiped out. 01422 */ 01423 *cp = 0; 01424 } 01425 } 01426 /* If there are remnants left over, or perhaps the news file isn't 01427 * formatted with % headers, display what we have got. 01428 */ 01429 if (*mynews != 0) 01430 add_marked_text_to_pane(&login_pane[TEXTVIEW_NEWS], mynews, 0, 0, 0); 01431 } 01432 } 01433 else if (type == INFO_MOTD) { 01434 gtk_text_buffer_set_text(textbuf_motd, "", 0); 01435 if (motd) 01436 add_marked_text_to_pane(&login_pane[TEXTVIEW_MOTD], motd, 0, 0, 0); 01437 } 01438 else if (type == INFO_RULES) { 01439 gtk_text_buffer_set_text(textbuf_rules_account, "", 0); 01440 gtk_text_buffer_set_text(textbuf_rules_char, "", 0); 01441 01442 if (rules) { 01443 add_marked_text_to_pane(&login_pane[TEXTVIEW_RULES_ACCOUNT], rules, 0, 0, 0); 01444 add_marked_text_to_pane(&login_pane[TEXTVIEW_RULES_CHAR], rules, 0, 0, 0); 01445 } 01446 } 01447 } 01448 01457 void start_login(int method) 01458 { 01459 /* Store this away - if method is only 1, we can not do smart character 01460 * creation. 01461 */ 01462 serverloginmethod = method; 01463 01464 if (!has_init) { 01465 /* Since there are 4 windows associated with account and character 01466 * login, to make life a little easier, each section here does all the 01467 * work for one window, so it is easier to see that everything for a 01468 * window is done - don't need to hunt through what would otherwise be 01469 * a long routine looking for entries. 01470 */ 01471 init_login_window(); 01472 01473 init_add_character_window(); 01474 01475 init_choose_char_window(); 01476 01477 init_create_account_window(); 01478 01479 init_new_character_window(); 01480 01481 init_account_password_window(); 01482 01483 has_init=1; 01484 01485 /* In case we have gotten news/motd/rules before getting here, update 01486 * it now. 01487 */ 01488 update_login_info(INFO_NEWS); 01489 update_login_info(INFO_RULES); 01490 update_login_info(INFO_MOTD); 01491 } 01492 01493 gtk_entry_set_text(GTK_ENTRY(entry_account_name), ""); 01494 gtk_entry_set_text(GTK_ENTRY(entry_account_password), ""); 01495 /* We set focus to account name - this makes the most sense if user is 01496 * logging in again - it is possible that the password is active, but both 01497 * fields are blank, which is not what is expected. 01498 */ 01499 gtk_widget_grab_focus(entry_account_name); 01500 gtk_widget_show(login_window); 01501 } 01502
1.7.6.1