Crossfire Client, Branch
R11627
|
00001 const char * const rcsid_gtk_gx11_c = 00002 "$Id: gx11.c 9581 2008-07-20 00:54:34Z kbulgrien $"; 00003 /* 00004 Crossfire client, a client program for the crossfire program. 00005 00006 Copyright (C) 2001-2003,2006-2007 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-devel@real-time.com 00023 */ 00024 00025 /* 00026 * This file contains the core window code. 00027 */ 00028 00029 /* Most functions in this file are private. Here is a list of 00030 * the global functions: 00031 * 00032 * draw_color_info(int color, char*buf) - draws text in specified color 00033 * draw_info - draw info in the info window 00034 * end_windows - used when exiting 00035 * init_windows - called when starting up 00036 * load_images - creates the bitmaps and pixmaps (if being used) 00037 * create_pixmap - creates a pixmap from given file and assigns to 00038 * the given face 00039 * create_xpm - as create_pixmap, but does an XPM image 00040 * load_additional_images - loads images that have been downloaded 00041 * from the server in prior sessions 00042 * 00043 * draw_stats(int) - draws the stat window. Pass 1 to redraw all 00044 * stats, not only those that changed 00045 * 00046 * draw_message_window(int) - draws the message window. Pass 1 to redraw 00047 * all the bars, not only those that changed. 00048 * 00049 * NOTE: create_pixmap and create_xpm can be empty functions if the 00050 * client will always use fonts - in that case, it should never 00051 * request Bitmap or Pixmap data, and thus not need the create 00052 * functions above 00053 * 00054 * Only functions in this file should be calling functions like 00055 * draw_stats and draw_message_window with redraw set - functions 00056 * in other files should always pass 0, because they will never have 00057 * the information of whether a redraw is needed. 00058 */ 00059 00060 00061 #include <config.h> 00062 00063 #include <errno.h> 00064 00065 /* gtk */ 00066 #include <gtk/gtk.h> 00067 #ifndef WIN32 00068 #include <gdk/gdkx.h> 00069 #else 00070 #include <gdk/gdkwin32.h> 00071 #endif 00072 #include <gdk/gdkkeysyms.h> 00073 00074 #ifdef HAVE_SDL 00075 #include <SDL.h> 00076 #include <SDL_image.h> 00077 #endif 00078 00079 /* Always include our local headers after the system headers are included */ 00080 #include "client.h" 00081 /*#include "clientbmap.h"*/ 00082 #include "item.h" 00083 #include "pixmaps/crossfiretitle.xpm" 00084 #include "gx11.h" 00085 #include "gtkproto.h" 00086 #include <script.h> 00087 #include <p_cmd.h> 00088 #include <time.h> 00089 00090 #include "mapdata.h" 00091 00092 00093 #ifdef HAVE_SDL 00094 /* These are only used in SDL mode at current time */ 00095 extern SDL_Surface* mapsurface; 00096 #endif 00097 00098 static const char *const colorname[] = { 00099 "Black", /* 0 */ 00100 "White", /* 1 */ 00101 "Navy", /* 2 */ 00102 "Red", /* 3 */ 00103 "Orange", /* 4 */ 00104 "DodgerBlue", /* 5 */ 00105 "DarkOrange2", /* 6 */ 00106 "SeaGreen", /* 7 */ 00107 "DarkSeaGreen", /* 8 */ /* Used for window background color */ 00108 "Grey50", /* 9 */ 00109 "Sienna", /* 10 */ 00110 "Gold", /* 11 */ 00111 "Khaki" /* 12 */ 00112 }; 00113 00114 #define DEFAULT_IMAGE_SIZE 32 00115 00116 int image_size=DEFAULT_IMAGE_SIZE; 00117 int map_image_size=DEFAULT_IMAGE_SIZE, map_image_half_size=DEFAULT_IMAGE_SIZE/2; 00118 PixmapInfo *pixmaps[MAXPIXMAPNUM]; 00119 00120 00121 /* Copy from server: include/define.h */ 00122 #define PU_NOTHING 0x00000000 00123 00124 #define PU_DEBUG 0x10000000 00125 #define PU_INHIBIT 0x20000000 00126 #define PU_STOP 0x40000000 00127 #define PU_NEWMODE 0x80000000 00128 00129 #define PU_RATIO 0x0000000F 00130 00131 #define PU_FOOD 0x00000010 00132 #define PU_DRINK 0x00000020 00133 #define PU_VALUABLES 0x00000040 00134 #define PU_BOW 0x00000080 00135 00136 #define PU_ARROW 0x00000100 00137 #define PU_HELMET 0x00000200 00138 #define PU_SHIELD 0x00000400 00139 #define PU_ARMOUR 0x00000800 00140 00141 #define PU_BOOTS 0x00001000 00142 #define PU_GLOVES 0x00002000 00143 #define PU_CLOAK 0x00004000 00144 #define PU_KEY 0x00008000 00145 00146 #define PU_MISSILEWEAPON 0x00010000 00147 #define PU_ALLWEAPON 0x00020000 00148 #define PU_MAGICAL 0x00040000 00149 #define PU_POTION 0x00080000 00150 00151 #define PU_SPELLBOOK 0x00100000 00152 #define PU_SKILLSCROLL 0x00200000 00153 #define PU_READABLES 0x00400000 00154 #define PU_MAGIC_DEVICE 0x00800000 00155 00156 #define PU_NOT_CURSED 0x01000000 00157 #define PU_JEWELS 0x02000000 00158 #define PU_FLESH 0x04000000 00159 00160 00161 00162 typedef struct { 00163 GtkWidget *playername; 00164 GtkWidget *score; 00165 GtkWidget *level; 00166 GtkWidget *hp; 00167 GtkWidget *sp; 00168 GtkWidget *gr; 00169 GtkWidget *Str; 00170 GtkWidget *Dex; 00171 GtkWidget *Con; 00172 GtkWidget *Int; 00173 GtkWidget *Wis; 00174 GtkWidget *Cha; 00175 GtkWidget *Pow; 00176 GtkWidget *wc; 00177 GtkWidget *dam; 00178 GtkWidget *ac; 00179 GtkWidget *armor; 00180 GtkWidget *speed; 00181 GtkWidget *food; 00182 GtkWidget *skill; 00183 GtkWidget *skill_exp[MAX_SKILL*2]; 00184 } StatWindow; 00185 00186 static char **gargv; 00187 00188 #define MAX_HISTORY 50 00189 #define MAX_COMMAND_LEN 256 00190 static char history[MAX_HISTORY][MAX_COMMAND_LEN]; 00191 static int cur_history_position=0, scroll_history_position=0; 00192 00193 extern int maxfd; 00194 struct timeval timeout; 00195 static gint csocket_fd = 0; 00196 00197 static int gargc; 00198 00199 static uint8 00200 bigmap=FALSE; /* True if we've moved some windows around for big maps */ 00201 00202 uint8 00203 time_map_redraw=FALSE, 00204 updatekeycodes=FALSE, 00205 redraw_needed=FALSE; 00206 00207 00208 /* Default size of scroll buffers is 100 K */ 00209 static int info1_num_chars=0, info2_num_chars=0, info1_max_chars=100000, 00210 info2_max_chars=100000; 00211 00212 00213 typedef struct { 00214 int x; 00215 int y; 00216 } MapPos; 00217 00218 00219 /* vitals window */ 00220 00221 typedef struct { 00222 GtkWidget *bar; 00223 GtkStyle *style[2]; 00224 int state; 00225 } Vitals; 00226 00227 static Vitals vitals[4]; 00228 GtkWidget *run_label, *fire_label; 00229 static GtkWidget *restable; /* resistance table */ 00230 static GtkWidget *res_scrolled_window; /* window the resistances are in */ 00231 static GtkWidget *skill_scrolled_window; /* window the skills are in */ 00232 00233 00234 static GtkWidget *resists[NUM_RESISTS]; 00235 GtkWidget *ckentrytext, *ckeyentrytext, *cmodentrytext, *cnumentrytext; 00236 00237 GdkColor gdk_green = { 0, 0, 0xcfff, 0 }; 00238 GdkColor gdk_red = { 0, 0xcfff, 0, 0 }; 00239 GdkColor gdk_grey = { 0, 0xea60, 0xea60, 0xea60 }; 00240 GdkColor gdk_black = { 0, 0, 0, 0 }; 00241 00242 static GdkColor map_color[16]; 00243 /* Not static so it can be used in inventory.c for highlighting. */ 00244 GdkColor root_color[16]; 00245 static GdkPixmap *magicgdkpixmap; 00246 static GdkGC *magic_map_gc; 00247 static GtkWidget *mapvbox; 00248 GdkPixmap *mapwindow; 00249 GdkBitmap *dark1, *dark2, *dark3; 00250 GdkPixmap *dark; 00251 00252 GtkTooltips *tooltips; 00253 00254 static GtkWidget *dialogtext; 00255 static GtkWidget *dialog_window; 00256 GtkWidget *drawingarea; 00257 00258 GdkGC *mapgc; 00259 00260 GtkWidget *cclist; 00261 static gboolean draw_info_freeze1=FALSE, draw_info_freeze2=FALSE; 00262 00263 enum { 00264 locked_icon = 1, applied_icon, unpaid_icon, 00265 damned_icon, cursed_icon, magic_icon, close_icon, 00266 stipple1_icon, stipple2_icon, max_icons 00267 }; 00268 00269 00270 GtkWidget *entrytext; /* "Command-line" frame, built in get_info_display(). */ 00271 static GtkObject *text_hadj,*text_vadj; 00272 static GtkObject *text_hadj2,*text_vadj2; 00273 static GtkWidget *gameframe, *stat_frame, *message_frame; 00274 00275 static StatWindow statwindow; 00276 /* gtk */ 00277 00278 GtkWidget *gtkwin_root, *gtkwin_info; 00279 GtkWidget *gtkwin_info_text; /* Referenced by inventory::count_callback. */ 00280 GtkWidget *gtkwin_info_text2; /* Used when CONFIG_SPLITINFO */ 00281 GtkWidget *gtkwin_stats, *gtkwin_message, *gtkwin_look, *gtkwin_inv; 00282 00283 00284 static GtkWidget *gtkwin_about = NULL; 00285 static GtkWidget *gtkwin_bug = NULL; 00286 static GtkWidget *gtkwin_splash = NULL; 00287 static GtkWidget *gtkwin_shelp = NULL; 00288 static GtkWidget *gtkwin_magicmap = NULL; 00289 00290 static GtkWidget *bugtrack = NULL; 00291 00292 /* These are the panes used in splitting up the window in non root 00293 * windows mode. Need to be globals so we can get/set the 00294 * information when loading/saving the positions. 00295 */ 00296 00297 static GtkWidget 00298 *inv_hpane, /* Split between inv,message window and stats/game/.. window */ 00299 *stat_info_hpane, /* Game/stats on left, info windows on right */ 00300 *stat_game_vpane, /* Status window/game window split */ 00301 *game_bar_vpane, /* Game/scroll split */ 00302 *inv_look_vpane, /* Inventory/look split */ 00303 *info_vpane; /* Split for 2 info windows */ 00304 00305 static char *last_str; 00306 00308 static unsigned int pickup_mode = 0; 00309 00310 int updatelock = 0; 00311 00312 /* This is used for caching the images across runs. When we get a face 00313 * command from the server, we check the facecache for that name. If 00314 * so, we can then use the num to find out what face number it is on the 00315 * local side. 00316 */ 00317 struct FaceCache { 00318 char *name; 00319 uint16 num; 00320 } facecache[MAXPIXMAPNUM]; 00321 00322 int misses=0,total=0; 00323 00324 void disconnect(GtkWidget *widget); 00325 00326 /* Called from disconnect command - that closes the socket - 00327 * we just need to do the gtk cleanup. 00328 */ 00329 void cleanup_connection(void) { 00330 if (csocket_fd) { 00331 gdk_input_remove(csocket_fd); 00332 csocket_fd=0; 00333 gtk_main_quit(); 00334 } 00335 cleanup_textmanagers(); 00336 } 00337 00338 /* Main loop iteration related stuff */ 00339 static void do_network(void) { 00340 fd_set tmp_read; 00341 int pollret; 00342 extern int updatelock; 00343 00344 if (csocket.fd==-1) { 00345 if (csocket_fd) { 00346 gdk_input_remove(csocket_fd); 00347 csocket_fd=0; 00348 gtk_main_quit(); 00349 } 00350 return; 00351 } 00352 00353 if (updatelock < 20) { 00354 FD_ZERO(&tmp_read); 00355 FD_SET(csocket.fd, &tmp_read); 00356 script_fdset(&maxfd,&tmp_read); 00357 pollret = select(maxfd, &tmp_read, NULL, NULL, &timeout); 00358 if (pollret==-1) { 00359 LOG(LOG_WARNING,"gtk::do_network", "Got errno %d on select call.", errno); 00360 } 00361 else if ( pollret>0 ) { 00362 if (FD_ISSET(csocket.fd, &tmp_read)) { 00363 DoClient(&csocket); 00364 #ifndef WIN32 00365 if ( pollret > 1 ) script_process(&tmp_read); 00366 #endif 00367 } 00368 else { 00369 script_process(&tmp_read); 00370 } 00371 } 00372 } else { 00373 LOG(LOG_INFO,"gtk::do_network","locked for network recieves.\n"); 00374 } 00375 if (csocket.fd==-1) { 00376 if (csocket_fd) { 00377 gdk_input_remove(csocket_fd); 00378 csocket_fd=0; 00379 gtk_main_quit(); 00380 } 00381 return; 00382 } 00383 00384 } 00385 00386 #ifdef WIN32 /* Win32 scripting support */ 00387 int do_scriptout(void) 00388 { 00389 script_process(NULL); 00390 return(TRUE); 00391 } 00392 #endif /* WIN32 */ 00393 00394 static void event_loop(void) 00395 { 00396 gint fleep; 00397 extern int do_timeout(void); /* forward */ 00398 int tag; 00399 00400 if (MAX_TIME==0) { 00401 timeout.tv_sec = 0; 00402 timeout.tv_usec = 0; 00403 } 00404 maxfd = csocket.fd + 1; 00405 00406 if (MAX_TIME!=0) { 00407 timeout.tv_sec = 0;/* MAX_TIME / 1000000;*/ 00408 timeout.tv_usec = 0;/* MAX_TIME % 1000000;*/ 00409 } 00410 00411 fleep = gtk_timeout_add (100, 00412 (GtkFunction) do_timeout, 00413 NULL); 00414 00415 #ifdef WIN32 00416 gtk_timeout_add (25, (GtkFunction) do_scriptout, NULL); 00417 #endif 00418 00419 csocket_fd = gdk_input_add ((gint) csocket.fd, 00420 GDK_INPUT_READ, 00421 (GdkInputFunction) do_network, &csocket); 00422 tag = csocket_fd; 00423 00424 gtk_main(); 00425 gtk_timeout_remove(tag); 00426 00427 cleanup_textmanagers(); 00428 LOG(LOG_INFO,"gtk::event_loop","gtk_main exited, returning from event_loop"); 00429 } 00430 00431 00432 00433 00434 /* Handle mouse presses in the game window */ 00435 00436 static void button_map_event(GtkWidget *widget, GdkEventButton *event) { 00437 int dx, dy, i, x, y, xmidl, xmidh, ymidl, ymidh; 00438 00439 x=(int)event->x; 00440 y=(int)event->y; 00441 dx=(x-2)/map_image_size-(use_config[CONFIG_MAPWIDTH]/2); 00442 dy=(y-2)/map_image_size-(use_config[CONFIG_MAPHEIGHT]/2); 00443 xmidl=(use_config[CONFIG_MAPWIDTH]/2) * map_image_size; 00444 xmidh=(use_config[CONFIG_MAPWIDTH]/2 + 1) * map_image_size; 00445 ymidl=(use_config[CONFIG_MAPHEIGHT]/2) * map_image_size; 00446 ymidh=(use_config[CONFIG_MAPHEIGHT]/2 + 1) * map_image_size; 00447 00448 switch (event->button) { 00449 case 1: 00450 look_at(dx,dy); 00451 break; 00452 00453 case 2: 00454 case 3: 00455 if (x<xmidl) 00456 i = 0; 00457 else if (x>xmidh) 00458 i = 6; 00459 else i =3; 00460 00461 if (y>ymidh) 00462 i += 2; 00463 else if (y>ymidl) 00464 i++; 00465 00466 if (event->button==2) { 00467 switch (i) { 00468 case 0: fire_dir (8);break; 00469 case 1: fire_dir (7);break; 00470 case 2: fire_dir (6);break; 00471 case 3: fire_dir (1);break; 00472 case 5: fire_dir (5);break; 00473 case 6: fire_dir (2);break; 00474 case 7: fire_dir (3);break; 00475 case 8: fire_dir (4);break; 00476 } 00477 /* Only want to fire once */ 00478 clear_fire(); 00479 } 00480 else switch (i) { 00481 case 0: move_player (8);break; 00482 case 1: move_player (7);break; 00483 case 2: move_player (6);break; 00484 case 3: move_player (1);break; 00485 case 5: move_player (5);break; 00486 case 6: move_player (2);break; 00487 case 7: move_player (3);break; 00488 case 8: move_player (4);break; 00489 } 00490 } 00491 } 00492 00493 00494 00495 00496 00497 /****************************************************************************** 00498 * 00499 * Code related to face caching. 00500 * 00501 *****************************************************************************/ 00502 00503 /* Initializes the data for image caching */ 00504 static void init_cache_data(void) 00505 { 00506 int i; 00507 GtkStyle *style; 00508 #include "pixmaps/question.xpm" 00509 00510 00511 LOG(LOG_INFO,"gtk::init_cache_data","Init Cache"); 00512 00513 style = gtk_widget_get_style(gtkwin_root); 00514 pixmaps[0] = malloc(sizeof(PixmapInfo)); 00515 pixmaps[0]->icon_image = gdk_pixmap_create_from_xpm_d(gtkwin_root->window, 00516 (GdkBitmap**)&pixmaps[0]->icon_mask, 00517 &style->bg[GTK_STATE_NORMAL], 00518 (gchar **)question_xpm); 00519 #ifdef HAVE_SDL 00520 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) { 00521 /* Make a semi transparent question mark symbol to 00522 * use for the cached images. 00523 */ 00524 #include "pixmaps/question.sdl" 00525 pixmaps[0]->map_image = SDL_CreateRGBSurfaceFrom(question_sdl, 00526 32, 32, 1, 4, 1, 1, 1, 1); 00527 SDL_SetAlpha(pixmaps[0]->map_image, SDL_SRCALPHA, 70); 00528 pixmaps[0]->fog_image = SDL_CreateRGBSurfaceFrom(question_sdl, 00529 32, 32, 1, 4, 1, 1, 1, 1); 00530 SDL_SetAlpha(pixmaps[0]->fog_image, SDL_SRCALPHA, 70); 00531 } 00532 else 00533 #endif 00534 { 00535 pixmaps[0]->map_image = pixmaps[0]->icon_image; 00536 pixmaps[0]->fog_image = pixmaps[0]->icon_image; 00537 pixmaps[0]->map_mask = pixmaps[0]->icon_mask; 00538 } 00539 pixmaps[0]->icon_width = pixmaps[0]->icon_height = pixmaps[0]->map_width = pixmaps[0]->map_height = map_image_size; 00540 pixmaps[0]->smooth_face = 0; 00541 00542 /* Don't do anything special for SDL image - rather, that drawing 00543 * code will check to see if there is no data 00544 */ 00545 00546 /* Initialize all the images to be of the same value. */ 00547 for (i=1; i<MAXPIXMAPNUM; i++) { 00548 pixmaps[i] = pixmaps[0]; 00549 } 00550 00551 init_common_cache_data(); 00552 } 00553 00554 /* Deals with command history. If direction is 0, we are going backwards, 00555 * if 1, we are moving forward. 00556 */ 00557 00558 void gtk_command_history(int direction) 00559 { 00560 int i=scroll_history_position; 00561 if (direction) { 00562 i--; 00563 if (i<0) i+=MAX_HISTORY; 00564 if (i == cur_history_position) return; 00565 } else { 00566 i++; 00567 if (i>=MAX_HISTORY) i = 0; 00568 if (i == cur_history_position) { 00569 /* User has forwarded to what should be current entry - reset it now. */ 00570 gtk_entry_set_text(GTK_ENTRY(entrytext), ""); 00571 gtk_entry_set_position(GTK_ENTRY(entrytext), 0); 00572 scroll_history_position=cur_history_position; 00573 return; 00574 } 00575 } 00576 00577 if (history[i][0] == 0) return; 00578 00579 scroll_history_position=i; 00580 /* fprintf(stderr,"resetting postion to %d, data = %s\n", i, history[i]);*/ 00581 gtk_entry_set_text(GTK_ENTRY(entrytext), history[i]); 00582 gtk_entry_set_position(GTK_ENTRY(entrytext), strlen(history[i])); 00583 gtk_widget_grab_focus (GTK_WIDGET(entrytext)); 00584 cpl.input_state = Command_Mode; 00585 } 00586 00587 void gtk_complete_command(void) 00588 { 00589 const gchar *entry_text, *newcommand; 00590 00591 entry_text = gtk_entry_get_text(GTK_ENTRY(entrytext)); 00592 newcommand = complete_command(entry_text); 00593 /* Value differ, so update window */ 00594 if (newcommand != NULL) { 00595 /* Set position to last character */ 00596 gtk_entry_set_text(GTK_ENTRY(entrytext), newcommand); 00597 } 00598 else 00599 /* Grab focus anyway, key can be used somewhere, prevent other handlers */ 00600 gtk_widget_grab_focus (GTK_WIDGET(entrytext)); 00601 gtk_entry_set_position(GTK_ENTRY(entrytext), -1); 00602 } 00603 00604 00605 /* Event handlers for map drawing area */ 00606 /* For a reason I don't know, this gets called a whole bunch. 00607 * every time a monster is killed, this gets called for a reason 00608 * I can't figure out. 00609 */ 00610 00611 static gint 00612 configure_event (GtkWidget *widget, GdkEventConfigure *event) 00613 { 00614 static sint16 ox=-1, oy=-1; 00615 00616 /* Handle the surplus number of events that this causes to be generated. 00617 * Basically, if the size of the window hasn't changed, we really don't 00618 * care - position of the window isn't important. 00619 * Note that we could be more clever and free up the other data even on 00620 * requests that do change the size, 00621 * but this will fix the most horrendous memory leak 00622 */ 00623 if (event->type == GDK_CONFIGURE) { 00624 if (((GdkEventConfigure*)event)->width == ox && ((GdkEventConfigure*)event)->height == oy) 00625 return TRUE; 00626 else { 00627 #if 0 00628 fprintf(stderr, "ox=%d != %d, oy=%d != %d\n", ox, ((GdkEventConfigure*)event)->width, 00629 oy, ((GdkEventConfigure*)event)->height); 00630 #endif 00631 ox = ((GdkEventConfigure*)event)->width; 00632 oy = ((GdkEventConfigure*)event)->height; 00633 } 00634 } 00635 00636 #ifdef HAVE_SDL 00637 if(use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) { 00638 /* When program first runs, mapsurface can be null. 00639 * Either way, we want to catch it here. 00640 */ 00641 if (mapsurface) 00642 SDL_UpdateRect( mapsurface, 0, 0, 0, 0); 00643 return TRUE; 00644 } 00645 #endif 00646 00647 mapgc = gdk_gc_new (drawingarea->window); 00648 00649 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_PIXMAP) { 00650 int x,y,count; 00651 GdkGC *darkgc; 00652 00653 /* This is used when drawing with GdkPixmaps. Create another surface, 00654 * as well as some light/dark images 00655 */ 00656 dark = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, -1); 00657 gdk_draw_rectangle(dark, drawingarea->style->black_gc, TRUE, 0, 0, map_image_size, map_image_size); 00658 dark1 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1); 00659 dark2 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1); 00660 dark3 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1); 00661 00662 /* We need our own GC here because we are working with single bit depth images */ 00663 darkgc = gdk_gc_new(dark1); 00664 gdk_gc_set_foreground(darkgc, &root_color[NDI_WHITE]); 00665 /* Clear any garbage values we get when we create the bitmaps */ 00666 gdk_draw_rectangle(dark1, darkgc, TRUE, 0, 0, map_image_size, map_image_size); 00667 gdk_draw_rectangle(dark2, darkgc, TRUE, 0, 0, map_image_size, map_image_size); 00668 gdk_draw_rectangle(dark3, darkgc, TRUE, 0, 0, map_image_size, map_image_size); 00669 gdk_gc_set_foreground(darkgc, &root_color[NDI_BLACK]); 00670 count=0; 00671 for (x=0; x<map_image_size; x++) { 00672 for (y=0; y<map_image_size; y++) { 00673 00674 /* We just fill in points every X pixels - dark1 is the darkest, dark3 is the lightest. 00675 * dark1 has 50% of the pixels filled in, dark2 has 33%, dark3 has 25% 00676 * The formulae here are not perfect - dark2 will not match perfectly with an 00677 * adjacent dark2 image. dark3 results in diagonal stripes. OTOH, these will 00678 * change depending on the image size. 00679 */ 00680 if ((x+y) % 2) { 00681 gdk_draw_point(dark1, darkgc, x, y); 00682 } 00683 if ((x+y) %3) { 00684 gdk_draw_point(dark2, darkgc, x, y); 00685 } 00686 if ((x+y) % 4) { 00687 gdk_draw_point(dark3, darkgc, x, y); 00688 } 00689 /* dark1 gets filled on 0x01, 0x11, 0x10, only leaving 0x00 empty */ 00690 } 00691 /* If the row size is even, we put an extra value in count - in this 00692 * way, the pixels will be even on one line, odd on the next, etc 00693 * instead of vertical lines - at least for dark1 and dark3 00694 */ 00695 } 00696 mapwindow = gdk_pixmap_new(gtkwin_root->window, use_config[CONFIG_MAPWIDTH] * map_image_size, use_config[CONFIG_MAPHEIGHT] * map_image_size, -1); 00697 gdk_gc_unref(darkgc); 00698 } 00699 display_map_doneupdate(TRUE, FALSE); 00700 return TRUE; 00701 } 00702 00703 00704 00705 /* Redraw the screen from the backing pixmap */ 00706 static gint 00707 expose_event (GtkWidget *widget, GdkEventExpose *event) 00708 { 00709 #ifdef HAVE_SDL 00710 if(use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL && mapsurface) { 00711 SDL_UpdateRect( mapsurface, 0, 0, 0, 0); 00712 return FALSE; 00713 } 00714 #endif 00715 display_map_doneupdate(FALSE, FALSE); 00716 return FALSE; 00717 } 00718 00719 /* 00720 * Sets up player game view window, implemented as a gtk table. Cells are initialized 00721 * with the bg.xpm pixmap to avoid resizes and to initialize GC's and everything for the 00722 * actual drawing routines later. 00723 */ 00724 00725 static int get_game_display(GtkWidget *frame) { 00726 GtkWidget *gtvbox, *gthbox; 00727 00728 gtvbox = gtk_vbox_new (FALSE, 0); 00729 gtk_container_add (GTK_CONTAINER (frame), gtvbox); 00730 gthbox = gtk_hbox_new (FALSE, 0); 00731 gtk_box_pack_start (GTK_BOX (gtvbox), gthbox, FALSE, FALSE, 1); 00732 00733 drawingarea = gtk_drawing_area_new(); 00734 gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), map_image_size*use_config[CONFIG_MAPWIDTH],map_image_size*use_config[CONFIG_MAPHEIGHT]); 00735 /* Add mouseclick events to the drawing area */ 00736 00737 gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK); 00738 00739 /* Set up X redraw routine signalling */ 00740 gtk_signal_connect (GTK_OBJECT (drawingarea), "expose_event", 00741 (GtkSignalFunc) expose_event, NULL); 00742 gtk_signal_connect (GTK_OBJECT(drawingarea),"configure_event", 00743 (GtkSignalFunc) configure_event, NULL); 00744 /* Set up handling of mouseclicks in map */ 00745 00746 gtk_signal_connect (GTK_OBJECT(drawingarea), 00747 "button_press_event", 00748 GTK_SIGNAL_FUNC(button_map_event), 00749 NULL); 00750 00751 /* Pack it up and show it */ 00752 00753 gtk_box_pack_start (GTK_BOX (gthbox), drawingarea, FALSE, FALSE, 1); 00754 00755 gtk_widget_show(drawingarea); 00756 00757 gtk_widget_show(gthbox); 00758 gtk_widget_show(gtvbox); 00759 00760 00761 gtk_signal_connect (GTK_OBJECT (frame), "expose_event", 00762 (GtkSignalFunc) expose_event, NULL); 00763 gtk_signal_connect (GTK_OBJECT(frame),"configure_event", 00764 (GtkSignalFunc) configure_event, NULL); 00765 00766 gtk_widget_show (frame); 00767 return 0; 00768 } 00769 00770 00771 00772 /****************************************************************************** 00773 * 00774 * The functions dealing with the info window follow 00775 * 00776 *****************************************************************************/ 00777 00778 00779 static void enter_callback(GtkWidget *widget, GtkWidget *entry) 00780 { 00781 const gchar *entry_text; 00782 00783 /* Next reply will reset this as necessary */ 00784 gtk_entry_set_visibility(GTK_ENTRY(entrytext), TRUE); 00785 00786 entry_text = gtk_entry_get_text(GTK_ENTRY(entrytext)); 00787 /* printf("Entry contents: %s\n", entry_text);*/ 00788 00789 if (cpl.input_state==Metaserver_Select) { 00790 strcpy(cpl.input_text, entry_text); 00791 } else if (cpl.input_state == Reply_One || 00792 cpl.input_state == Reply_Many) { 00793 cpl.input_state = Playing; 00794 strcpy(cpl.input_text, entry_text); 00795 if (cpl.input_state == Reply_One) 00796 cpl.input_text[1] = 0; 00797 00798 send_reply(cpl.input_text); 00799 00800 } else { 00801 cpl.input_state = Playing; 00802 /* No reason to do anything for a null string */ 00803 if (entry_text[0] != 0) { 00804 strncpy(history[cur_history_position], entry_text, MAX_COMMAND_LEN); 00805 history[cur_history_position][MAX_COMMAND_LEN-1] = 0; 00806 cur_history_position++; 00807 cur_history_position %= MAX_HISTORY; 00808 scroll_history_position = cur_history_position; 00809 extended_command(entry_text); 00810 } 00811 } 00812 gtk_entry_set_text(GTK_ENTRY(entrytext),""); 00813 gtk_widget_grab_focus (GTK_WIDGET(gtkwin_info_text)); 00814 00815 if( cpl.input_state == Metaserver_Select) 00816 { 00817 cpl.input_state= Playing; 00818 /* This is the gtk_main that is started up by get_metaserver 00819 * The client will start another one once it is connected 00820 * to a crossfire server 00821 */ 00822 gtk_main_quit(); 00823 } 00824 } 00825 00826 /* Can use a wheeled mouse to scroll the info window */ 00827 static gboolean 00828 info_text_button_press_event (GtkWidget *widget, GdkEventButton *event, 00829 gpointer user_data) 00830 { 00831 GtkAdjustment *vadj; 00832 gboolean shifted; 00833 gfloat v_value; 00834 00835 vadj = GTK_TEXT (widget)->vadj; 00836 v_value = vadj->value; 00837 00838 shifted = (event->state & GDK_SHIFT_MASK) != 0; 00839 00840 switch (event->button) 00841 { 00842 case 4: 00843 if (shifted) 00844 v_value -= vadj->page_size; 00845 else 00846 v_value -= vadj->step_increment * 5; 00847 break; 00848 00849 case 5: 00850 if (shifted) 00851 v_value += vadj->page_size; 00852 else 00853 v_value += vadj->step_increment * 5; 00854 break; 00855 00856 default: 00857 return FALSE; 00858 } 00859 00860 v_value = CLAMP (v_value, vadj->lower, vadj->upper - vadj->page_size); 00861 00862 gtk_adjustment_set_value (vadj, v_value); 00863 00864 return TRUE; 00865 } 00866 00867 static int get_info_display(GtkWidget *frame) { 00868 GtkWidget *box1; 00869 GtkWidget *box2; 00870 GtkWidget *tablet; 00871 GtkWidget *vscrollbar; 00872 FILE *infile; 00873 00874 box1 = gtk_vbox_new (FALSE, 0); 00875 if (use_config[CONFIG_SPLITINFO]) { 00876 info_vpane = gtk_vpaned_new(); 00877 gtk_container_add (GTK_CONTAINER (frame), info_vpane); 00878 gtk_widget_show(info_vpane); 00879 gtk_paned_add2(GTK_PANED(info_vpane), box1); 00880 } else { 00881 gtk_container_add (GTK_CONTAINER (frame), box1); 00882 } 00883 gtk_widget_show (box1); 00884 00885 box2 = gtk_vbox_new (FALSE, 3); 00886 gtk_container_border_width (GTK_CONTAINER (box2), 3); 00887 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 00888 gtk_widget_show (box2); 00889 00890 00891 tablet = gtk_table_new (2, 2, FALSE); 00892 gtk_table_set_row_spacing (GTK_TABLE (tablet), 0, 2); 00893 gtk_table_set_col_spacing (GTK_TABLE (tablet), 0, 2); 00894 gtk_box_pack_start (GTK_BOX (box2), tablet, TRUE, TRUE, 0); 00895 gtk_widget_show (tablet); 00896 00897 text_hadj = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40); 00898 text_vadj = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40); 00899 00900 gtkwin_info_text = gtk_text_new (GTK_ADJUSTMENT(text_hadj),GTK_ADJUSTMENT(text_vadj)); 00901 gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), FALSE); 00902 gtk_table_attach (GTK_TABLE (tablet), gtkwin_info_text, 0, 1, 0, 1, 00903 GTK_EXPAND | GTK_SHRINK | GTK_FILL, 00904 GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); 00905 gtk_widget_show (gtkwin_info_text); 00906 00907 00908 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (gtkwin_info_text)->vadj); 00909 gtk_table_attach (GTK_TABLE (tablet), vscrollbar, 1, 2, 0, 1, 00910 GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); 00911 gtk_widget_show (vscrollbar); 00912 00913 gtk_signal_connect (GTK_OBJECT (gtkwin_info_text), "button_press_event", 00914 GTK_SIGNAL_FUNC (info_text_button_press_event), 00915 vscrollbar); 00916 00917 gtk_text_freeze (GTK_TEXT (gtkwin_info_text)); 00918 00919 gtk_widget_realize (gtkwin_info_text); 00920 00921 if (use_config[CONFIG_SPLITINFO]) { 00922 00923 box1 = gtk_vbox_new (FALSE, 0); 00924 gtk_widget_show (box1); 00925 gtk_paned_add1(GTK_PANED(info_vpane), box1); 00926 00927 tablet = gtk_table_new (2, 2, FALSE); 00928 gtk_table_set_row_spacing (GTK_TABLE (tablet), 0, 2); 00929 gtk_table_set_col_spacing (GTK_TABLE (tablet), 0, 2); 00930 gtk_box_pack_start (GTK_BOX (box1), tablet, TRUE, TRUE, 0); 00931 gtk_widget_show (tablet); 00932 00933 text_hadj2 = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40); 00934 text_vadj2 = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40); 00935 00936 gtkwin_info_text2 = gtk_text_new (GTK_ADJUSTMENT(text_hadj2),GTK_ADJUSTMENT(text_vadj2)); 00937 00938 gtk_text_set_editable (GTK_TEXT (gtkwin_info_text2), FALSE); 00939 gtk_table_attach (GTK_TABLE (tablet), gtkwin_info_text2, 0, 1, 0, 1, 00940 GTK_EXPAND | GTK_SHRINK | GTK_FILL, 00941 GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); 00942 gtk_widget_show (gtkwin_info_text2); 00943 00944 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (gtkwin_info_text2)->vadj); 00945 gtk_table_attach (GTK_TABLE (tablet), vscrollbar, 1, 2, 0, 1, 00946 GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0); 00947 gtk_widget_show (vscrollbar); 00948 gtk_signal_connect (GTK_OBJECT (gtkwin_info_text2), "button_press_event", 00949 GTK_SIGNAL_FUNC (info_text_button_press_event), 00950 vscrollbar); 00951 00952 gtk_widget_realize (gtkwin_info_text2); 00953 } 00954 00955 infile = fopen("Welcome", "r"); 00956 00957 if (infile) 00958 { 00959 char buffer[1024]; 00960 int nchars; 00961 00962 while (1) 00963 { 00964 nchars = fread(buffer, 1, 1024, infile); 00965 gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, NULL, 00966 NULL, buffer, nchars); 00967 00968 if (nchars < 1024) 00969 break; 00970 } 00971 00972 fclose (infile); 00973 } 00974 00975 gtk_text_thaw (GTK_TEXT (gtkwin_info_text)); 00976 00977 00978 entrytext = gtk_entry_new (); 00979 gtk_signal_connect(GTK_OBJECT(entrytext), "activate", 00980 GTK_SIGNAL_FUNC(enter_callback), 00981 entrytext); 00982 gtk_box_pack_start (GTK_BOX (box2),entrytext, FALSE, TRUE, 0); 00983 GTK_WIDGET_SET_FLAGS (entrytext, GTK_CAN_DEFAULT); 00984 gtk_widget_grab_default (entrytext); 00985 gtk_widget_show (entrytext); 00986 00987 return 0; 00988 } 00989 00990 /* Various replies */ 00991 00992 static void sendstr(char *sendstr) 00993 { 00994 gtk_widget_destroy (dialog_window); 00995 send_reply(sendstr); 00996 cpl.input_state = Playing; 00997 } 00998 00999 01000 /* This is similar to draw_info below, but doesn't advance to a new 01001 * line. Generally queries use this function to draw the prompt for 01002 * the name, password, etc. 01003 */ 01004 01005 01006 01007 static void dialog_callback(GtkWidget *dialog) 01008 { 01009 const gchar *dialog_text; 01010 dialog_text = gtk_entry_get_text(GTK_ENTRY(dialogtext)); 01011 send_reply(dialog_text); 01012 gtk_widget_destroy (dialog_window); 01013 cpl.input_state = Playing; 01014 } 01015 static GtkWidget *userText = NULL; 01016 static GtkWidget *passwordText = NULL; 01017 static GtkWidget *passwordText2 = NULL; 01018 static GtkWidget *loginWindow = NULL; 01019 static GtkWidget *motdText = NULL; 01020 static GtkWidget *rulesText = NULL; 01021 static GtkWidget *newsText = NULL; 01022 static GtkWidget *loginTabs = NULL; 01023 static GtkWidget *loginButtonOk = NULL; 01024 static GtkWidget *loginButtonCancel = NULL; 01025 static GtkWidget *loginMessage = NULL; 01026 01027 char password[64]=""; 01028 static void setUserPass(GtkButton *button, gpointer func_data) { 01029 gchar* user; 01030 gchar* pass; 01031 user=gtk_editable_get_chars (GTK_EDITABLE(userText),0,-1); 01032 pass=gtk_editable_get_chars (GTK_EDITABLE(passwordText),0,-1); 01033 strncpy(password,pass,sizeof(password)); 01034 send_reply(user); 01035 #ifdef MULTKEYS 01036 /* Now is a good time to load player's specific key bindings */ 01037 if (csocket.servername != NULL) 01038 sprintf(cpl.name, "%s.%s", user, csocket.servername); 01039 else 01040 strcpy( cpl.name, user ); 01041 init_keys( ); 01042 #endif 01043 cpl.input_state = Playing; 01044 g_free(user); 01045 g_free(pass); 01046 gtk_widget_hide(loginWindow); 01047 } 01048 static void confirmUserPass(GtkButton *button, gpointer func_data) { 01049 gchar* pass; 01050 pass=gtk_editable_get_chars (GTK_EDITABLE(passwordText2),0,-1); 01051 send_reply(pass); 01052 cpl.input_state = Playing; 01053 g_free(pass); 01054 gtk_widget_hide(loginWindow); 01055 } 01056 static void cancelConnection(GtkButton *button, gpointer func_data) { 01057 gtk_widget_hide(loginWindow); 01058 cpl.input_state = Metaserver_Select; 01059 disconnect(GTK_WIDGET(button)); 01060 } 01061 01062 static void disable_ok_if_empty(gpointer button, GtkEditable *entry) { 01063 gchar *passcontent,*txtcontent; 01064 txtcontent = gtk_editable_get_chars(GTK_EDITABLE(userText),0,-1); 01065 passcontent= gtk_editable_get_chars(GTK_EDITABLE(passwordText) ,0,-1); 01066 if ( passcontent && txtcontent && 01067 (strlen(txtcontent)>=1)&& 01068 (strlen(passcontent)>=1)) 01069 gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),TRUE); 01070 else 01071 gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),FALSE); 01072 if (txtcontent && (strlen (txtcontent)>0)) 01073 gtk_widget_show(passwordText); 01074 else 01075 gtk_widget_hide(passwordText); 01076 g_free(txtcontent); 01077 g_free(passcontent); 01078 } 01079 static void change_focus(GtkWidget *focusTo, GtkEditable *entry) { 01080 01081 char *txtcontent = gtk_editable_get_chars(entry,0,-1); 01082 /* printf("switch focus\n"); */ 01083 if (txtcontent && (strlen(txtcontent)>0)) 01084 gtk_widget_grab_focus(focusTo); 01085 } 01086 static void activate_ok_if_not_empty(GtkWidget *button, GtkEditable *entry) { 01087 char *txtcontent = gtk_editable_get_chars(entry,0,-1); 01088 if (txtcontent && (strlen(txtcontent)>0)) 01089 gtk_widget_activate(button); 01090 if (txtcontent) 01091 g_free(txtcontent); 01092 } 01093 static void fill_news(GtkWidget *o, news_entry *news) { 01094 media_state state; 01095 while(news){ 01096 state = write_media(GTK_TEXT(o),"[b]"); 01097 write_media_with_state(GTK_TEXT(o),news->title,state); 01098 write_media(GTK_TEXT(o),"\n\n"); 01099 write_media(GTK_TEXT(o),news->content); 01100 write_media(GTK_TEXT(o),"\n\n"); 01101 news=news->next; 01102 } 01103 } 01104 static gint dialog_delete_event_callback(GtkWidget *widget, GdkEvent *event, gpointer data) 01105 { 01106 loginWindow = NULL; 01107 return FALSE; 01108 } 01109 static void buildLoginDialog(void) { 01110 if (loginWindow==NULL){ 01111 /* Build window */ 01112 GtkWidget *vbox, *table, *label, *hbox, *vscroll; 01113 loginWindow= gtk_window_new(GTK_WINDOW_TOPLEVEL); 01114 gtk_window_set_policy (GTK_WINDOW (loginWindow), TRUE, TRUE, 01115 FALSE); 01116 gtk_window_set_transient_for (GTK_WINDOW (loginWindow), 01117 GTK_WINDOW (gtkwin_root)); 01118 gtk_window_set_title (GTK_WINDOW (loginWindow), "Login"); 01119 gtk_window_set_transient_for(GTK_WINDOW (loginWindow), 01120 GTK_WINDOW (gtkwin_root)); 01121 vbox=gtk_vbox_new(FALSE,4); 01122 01123 /* Build it's notebook */ 01124 loginTabs = gtk_notebook_new(); 01125 /* notebook -> news */ 01126 hbox=gtk_hbox_new(FALSE,2); 01127 newsText = gtk_text_new(NULL,NULL); 01128 gtk_text_set_word_wrap(GTK_TEXT(newsText),TRUE); 01129 gtk_text_set_line_wrap(GTK_TEXT(newsText),TRUE); 01130 vscroll = gtk_vscrollbar_new (GTK_TEXT (newsText)->vadj); 01131 gtk_box_pack_start(GTK_BOX(hbox),newsText,TRUE,TRUE,0); 01132 gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0); 01133 label = gtk_label_new("News"); 01134 gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),hbox,label); 01135 gtk_widget_show(vscroll); 01136 gtk_widget_show(newsText); 01137 gtk_widget_show(hbox); 01138 /* notebook -> rules */ 01139 hbox=gtk_hbox_new(FALSE,2); 01140 rulesText = gtk_text_new(NULL,NULL); 01141 gtk_text_set_word_wrap(GTK_TEXT(rulesText),TRUE); 01142 gtk_text_set_line_wrap(GTK_TEXT(rulesText),TRUE); 01143 vscroll = gtk_vscrollbar_new (GTK_TEXT (rulesText)->vadj); 01144 gtk_box_pack_start(GTK_BOX(hbox),rulesText,TRUE,TRUE,0); 01145 gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0); 01146 label = gtk_label_new("Rules"); 01147 gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),hbox,label); 01148 gtk_widget_show(vscroll); 01149 gtk_widget_show(rulesText); 01150 gtk_widget_show(hbox); 01151 01152 /* notebook -> login */ 01153 hbox=gtk_hbox_new(FALSE,2); 01154 motdText = gtk_text_new(NULL,NULL); 01155 vscroll = gtk_vscrollbar_new (GTK_TEXT (motdText)->vadj); 01156 gtk_box_pack_start(GTK_BOX(hbox),motdText,TRUE,TRUE,0); 01157 gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0); 01158 gtk_widget_show(hbox); 01159 gtk_widget_show(motdText); 01160 gtk_widget_show(vscroll); 01161 gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); 01162 01163 01164 /* Message information */ 01165 loginMessage = gtk_label_new(NULL); 01166 gtk_box_pack_start(GTK_BOX(vbox),loginMessage,FALSE,FALSE,0); 01167 gtk_widget_show(loginMessage); 01168 01169 /* user-pass table*/ 01170 table=gtk_table_new(3,2,FALSE); 01171 /* TODO for strange reason justify does not work. 01172 * May someone fix this?*/ 01173 label=gtk_label_new("User:"); 01174 gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,GTK_EXPAND|GTK_FILL,0,2,2); 01175 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT); 01176 gtk_widget_show(label); 01177 label=gtk_label_new("Password:"); 01178 gtk_table_attach(GTK_TABLE(table),label,0,1,1,2,GTK_EXPAND|GTK_FILL,0,2,2); 01179 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT); 01180 gtk_widget_show(label); 01181 label=gtk_label_new("Re-type password:"); 01182 gtk_table_attach(GTK_TABLE(table),label,0,1,2,3,GTK_EXPAND|GTK_FILL,0,2,2); 01183 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT); 01184 gtk_widget_show(label); 01185 userText=gtk_entry_new(); 01186 gtk_widget_show(userText); 01187 gtk_table_attach(GTK_TABLE(table),userText,1,2,0,1,GTK_EXPAND|GTK_FILL,0,2,2); 01188 passwordText= gtk_entry_new(); 01189 gtk_entry_set_visibility(GTK_ENTRY(passwordText),FALSE); 01190 gtk_widget_show(passwordText); 01191 gtk_table_attach(GTK_TABLE(table),passwordText,1,2,1,2,GTK_EXPAND|GTK_FILL,0,2,2); 01192 passwordText2= gtk_entry_new(); 01193 gtk_entry_set_visibility(GTK_ENTRY(passwordText2),FALSE); 01194 gtk_entry_set_editable(GTK_ENTRY(passwordText2),FALSE); 01195 gtk_table_attach(GTK_TABLE(table),passwordText2,1,2,2,3,GTK_EXPAND|GTK_FILL,0,2,2); 01196 gtk_widget_show(passwordText2); 01197 gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0); 01198 01199 01200 hbox=gtk_hbox_new(FALSE,2); 01201 loginButtonOk = gtk_button_new_with_label("Ok"); 01202 loginButtonCancel = gtk_button_new_with_label("Cancel"); 01203 gtk_box_pack_start(GTK_BOX(hbox),loginButtonOk,TRUE,FALSE,0); 01204 gtk_box_pack_start(GTK_BOX(hbox),loginButtonCancel,TRUE,FALSE,0); 01205 gtk_widget_show(hbox); 01206 gtk_widget_show(loginButtonOk); 01207 gtk_widget_show(loginButtonCancel); 01208 01209 /* Manage events on login widgets */ 01210 gtk_signal_connect_object (GTK_OBJECT (loginWindow), 01211 "delete_event", 01212 GTK_SIGNAL_FUNC (dialog_delete_event_callback), 01213 NULL); 01214 gtk_signal_connect_object (GTK_OBJECT (loginButtonCancel), 01215 "clicked", 01216 GTK_SIGNAL_FUNC (cancelConnection), 01217 NULL); 01218 gtk_signal_connect_object (GTK_OBJECT (userText), 01219 "changed", 01220 GTK_SIGNAL_FUNC (disable_ok_if_empty), 01221 GINT_TO_POINTER(loginButtonOk)); 01222 gtk_signal_connect_object (GTK_OBJECT (passwordText), 01223 "changed", 01224 GTK_SIGNAL_FUNC (disable_ok_if_empty), 01225 GINT_TO_POINTER(loginButtonOk)); 01226 gtk_signal_connect_object (GTK_OBJECT (userText), 01227 "activate", 01228 GTK_SIGNAL_FUNC (change_focus), 01229 GINT_TO_POINTER(passwordText)); 01230 gtk_signal_connect_object (GTK_OBJECT (userText), 01231 "activate", 01232 GTK_SIGNAL_FUNC (change_focus), 01233 GINT_TO_POINTER(passwordText)); 01234 gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); 01235 gtk_signal_connect_object (GTK_OBJECT (passwordText), 01236 "activate", 01237 GTK_SIGNAL_FUNC (activate_ok_if_not_empty), 01238 GINT_TO_POINTER(loginButtonOk)); 01239 gtk_signal_connect_object (GTK_OBJECT (passwordText2), 01240 "activate", 01241 GTK_SIGNAL_FUNC (activate_ok_if_not_empty), 01242 GINT_TO_POINTER(loginButtonOk)); 01243 gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); 01244 gtk_widget_show(table); 01245 gtk_widget_show(vbox); 01246 label=gtk_label_new("login"); 01247 gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),vbox,label); 01248 gtk_container_add(GTK_CONTAINER(loginWindow),loginTabs); 01249 gtk_widget_show(loginTabs); 01250 gtk_window_set_default_size(GTK_WINDOW(loginWindow),500,400); 01251 gtk_window_set_position(GTK_WINDOW(loginWindow),GTK_WIN_POS_CENTER); 01252 } 01253 gtk_editable_delete_text(GTK_EDITABLE(motdText),0,-1); 01254 write_media(GTK_TEXT(motdText), getMOTD()); 01255 gtk_editable_delete_text(GTK_EDITABLE(rulesText),0,-1); 01256 write_media(GTK_TEXT(rulesText),get_rules()); 01257 gtk_editable_delete_text(GTK_EDITABLE(newsText),0,-1); 01258 fill_news(newsText,get_news()); 01259 gtk_widget_show(loginWindow); 01260 } 01261 guint signalLoginDialogClicked = -1; 01262 static void logUserIn(void) { 01263 buildLoginDialog(); 01264 gtk_label_set_text(GTK_LABEL(loginMessage),"Type in user name and password"); 01265 gtk_entry_set_editable(GTK_ENTRY(userText),TRUE); 01266 gtk_entry_set_editable(GTK_ENTRY(passwordText),TRUE); 01267 gtk_entry_set_editable(GTK_ENTRY(passwordText2),FALSE); 01268 gtk_widget_show(GTK_WIDGET(passwordText)); 01269 gtk_widget_hide(GTK_WIDGET(passwordText2)); 01270 if (signalLoginDialogClicked!=-1) 01271 gtk_signal_disconnect(GTK_OBJECT (loginButtonOk), 01272 signalLoginDialogClicked); 01273 signalLoginDialogClicked = gtk_signal_connect_object (GTK_OBJECT (loginButtonOk), 01274 "clicked", 01275 GTK_SIGNAL_FUNC (setUserPass), 01276 NULL); 01277 gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),TRUE); 01278 gtk_entry_set_text(GTK_ENTRY(userText),""); 01279 gtk_entry_set_text(GTK_ENTRY(passwordText),""); 01280 gtk_entry_set_text(GTK_ENTRY(passwordText2),""); 01281 gtk_widget_grab_focus(userText); 01282 } 01283 static void sendPassword(void) { 01284 send_reply(password); 01285 cpl.input_state = Playing; 01286 } 01287 static void confirmPassword(void) { 01288 buildLoginDialog(); 01289 gtk_label_set_text(GTK_LABEL(loginMessage),"Creating new user, please confirm password"); 01290 gtk_entry_set_editable(GTK_ENTRY(userText),FALSE); 01291 gtk_entry_set_editable(GTK_ENTRY(passwordText),FALSE); 01292 gtk_entry_set_editable(GTK_ENTRY(passwordText2),TRUE); 01293 gtk_widget_hide(GTK_WIDGET(passwordText)); 01294 gtk_widget_show(GTK_WIDGET(passwordText2)); 01295 if (signalLoginDialogClicked!=-1) 01296 gtk_signal_disconnect(GTK_OBJECT (loginButtonOk), 01297 signalLoginDialogClicked); 01298 signalLoginDialogClicked = gtk_signal_connect_object (GTK_OBJECT (loginButtonOk), 01299 "clicked", 01300 GTK_SIGNAL_FUNC (confirmUserPass), 01301 NULL); 01302 gtk_widget_grab_focus(passwordText2); 01303 } 01304 /* Draw a prompt dialog window */ 01305 /* Ok, now this is trying to be smart and decide what sort of dialog is 01306 * wanted. 01307 */ 01308 01309 void 01310 draw_prompt (const char *str) 01311 { 01312 GtkWidget *dbox; 01313 GtkWidget *hbox; 01314 GtkWidget *dialoglabel; 01315 GtkWidget *yesbutton, *nobutton; 01316 GtkWidget *strbutton, *dexbutton, *conbutton, *intbutton, *wisbutton, 01317 *powbutton, *chabutton; 01318 01319 gint found = FALSE; 01320 01321 if (!use_config[CONFIG_POPUPS]) 01322 { 01323 draw_info(str, NDI_BLACK); 01324 } 01325 else 01326 { 01327 dialog_window = gtk_window_new (GTK_WINDOW_DIALOG); 01328 01329 gtk_window_set_policy (GTK_WINDOW (dialog_window), TRUE, TRUE, 01330 FALSE); 01331 gtk_window_set_title (GTK_WINDOW (dialog_window), "Dialog"); 01332 gtk_window_set_transient_for (GTK_WINDOW (dialog_window), 01333 GTK_WINDOW (gtkwin_root)); 01334 01335 dbox = gtk_vbox_new (FALSE, 6); 01336 gtk_container_add (GTK_CONTAINER (dialog_window), dbox); 01337 01338 /* Ok, here we start generating the contents */ 01339 01340 /* printf ("Last info draw: %s\n", last_str); */ 01341 while (!found) 01342 { 01343 if (!strcmp (str, ":")) 01344 { 01345 if (!strcmp (last_str, "What is your name?")) 01346 { 01347 logUserIn(); 01348 return; 01349 } 01350 01351 if (!strcmp (last_str, "What is your password?")) 01352 { 01353 sendPassword(); 01354 return; 01355 } 01356 if (!strcmp 01357 (last_str, "Please type your password again.")) 01358 { 01359 confirmPassword(); 01360 return; 01361 } 01362 } 01363 /* Ok, tricky ones. */ 01364 if (!strcmp (last_str, "[1-7] [1-7] to swap stats.") 01365 || !strncmp (last_str, "Str d", 5) 01366 || !strncmp (last_str, "Dex d", 5) 01367 || !strncmp (last_str, "Con d", 5) 01368 || !strncmp (last_str, "Int d", 5) 01369 || !strncmp (last_str, "Wis d", 5) 01370 || !strncmp (last_str, "Pow d", 5) 01371 || !strncmp (last_str, "Cha d", 5)) 01372 { 01373 01374 dialoglabel = 01375 gtk_label_new ("Roll again or exchange ability."); 01376 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01377 TRUE, 6); 01378 gtk_widget_show (dialoglabel); 01379 01380 hbox = gtk_hbox_new (TRUE, 2); 01381 strbutton = gtk_button_new_with_label ("Str"); 01382 gtk_box_pack_start (GTK_BOX (hbox), strbutton, TRUE, 01383 TRUE, 1); 01384 gtk_signal_connect_object (GTK_OBJECT (strbutton), 01385 "clicked", 01386 GTK_SIGNAL_FUNC (sendstr), 01387 GINT_TO_POINTER ("1")); 01388 01389 01390 dexbutton = gtk_button_new_with_label ("Dex"); 01391 gtk_box_pack_start (GTK_BOX (hbox), dexbutton, TRUE, 01392 TRUE, 1); 01393 gtk_signal_connect_object (GTK_OBJECT (dexbutton), 01394 "clicked", 01395 GTK_SIGNAL_FUNC (sendstr), 01396 GINT_TO_POINTER ("2")); 01397 01398 conbutton = gtk_button_new_with_label ("Con"); 01399 gtk_box_pack_start (GTK_BOX (hbox), conbutton, TRUE, 01400 TRUE, 1); 01401 gtk_signal_connect_object (GTK_OBJECT (conbutton), 01402 "clicked", 01403 GTK_SIGNAL_FUNC (sendstr), 01404 GINT_TO_POINTER ("3")); 01405 01406 intbutton = gtk_button_new_with_label ("Int"); 01407 gtk_box_pack_start (GTK_BOX (hbox), intbutton, TRUE, 01408 TRUE, 1); 01409 gtk_signal_connect_object (GTK_OBJECT (intbutton), 01410 "clicked", 01411 GTK_SIGNAL_FUNC (sendstr), 01412 GINT_TO_POINTER ("4")); 01413 01414 wisbutton = gtk_button_new_with_label ("Wis"); 01415 gtk_box_pack_start (GTK_BOX (hbox), wisbutton, TRUE, 01416 TRUE, 1); 01417 gtk_signal_connect_object (GTK_OBJECT (wisbutton), 01418 "clicked", 01419 GTK_SIGNAL_FUNC (sendstr), 01420 GINT_TO_POINTER ("5")); 01421 01422 powbutton = gtk_button_new_with_label ("Pow"); 01423 gtk_box_pack_start (GTK_BOX (hbox), powbutton, TRUE, 01424 TRUE, 1); 01425 gtk_signal_connect_object (GTK_OBJECT (powbutton), 01426 "clicked", 01427 GTK_SIGNAL_FUNC (sendstr), 01428 GINT_TO_POINTER ("6")); 01429 01430 chabutton = gtk_button_new_with_label ("Cha"); 01431 gtk_box_pack_start (GTK_BOX (hbox), chabutton, TRUE, 01432 TRUE, 1); 01433 gtk_signal_connect_object (GTK_OBJECT (chabutton), 01434 "clicked", 01435 GTK_SIGNAL_FUNC (sendstr), 01436 GINT_TO_POINTER ("7")); 01437 01438 gtk_widget_show (strbutton); 01439 gtk_widget_show (dexbutton); 01440 gtk_widget_show (conbutton); 01441 gtk_widget_show (intbutton); 01442 gtk_widget_show (wisbutton); 01443 gtk_widget_show (powbutton); 01444 gtk_widget_show (chabutton); 01445 01446 01447 01448 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01449 6); 01450 gtk_widget_show (hbox); 01451 01452 hbox = gtk_hbox_new (FALSE, 6); 01453 01454 yesbutton = gtk_button_new_with_label ("Roll again"); 01455 gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE, 01456 TRUE, 6); 01457 gtk_signal_connect_object (GTK_OBJECT (yesbutton), 01458 "clicked", 01459 GTK_SIGNAL_FUNC (sendstr), 01460 GINT_TO_POINTER ("y")); 01461 01462 nobutton = gtk_button_new_with_label ("Keep this"); 01463 gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE, 01464 TRUE, 6); 01465 gtk_signal_connect_object (GTK_OBJECT (nobutton), 01466 "clicked", 01467 GTK_SIGNAL_FUNC (sendstr), 01468 GINT_TO_POINTER ("n")); 01469 01470 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01471 6); 01472 01473 gtk_widget_show (yesbutton); 01474 gtk_widget_show (nobutton); 01475 gtk_widget_show (hbox); 01476 01477 found = TRUE; 01478 continue; 01479 } 01480 if (!strncmp (last_str, "Str -", 5) || 01481 !strncmp (last_str, "Dex -", 5) 01482 || !strncmp (last_str, "Con -", 5) 01483 || !strncmp (last_str, "Int -", 5) 01484 || !strncmp (last_str, "Wis -", 5) 01485 || !strncmp (last_str, "Pow -", 5) 01486 || !strncmp (last_str, "Cha -", 5)) 01487 { 01488 01489 01490 dialoglabel = 01491 gtk_label_new ("Exchange with which ability?"); 01492 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01493 TRUE, 6); 01494 gtk_widget_show (dialoglabel); 01495 01496 hbox = gtk_hbox_new (TRUE, 2); 01497 strbutton = gtk_button_new_with_label ("Str"); 01498 gtk_box_pack_start (GTK_BOX (hbox), strbutton, TRUE, 01499 TRUE, 1); 01500 gtk_signal_connect_object (GTK_OBJECT (strbutton), 01501 "clicked", 01502 GTK_SIGNAL_FUNC (sendstr), 01503 GINT_TO_POINTER ("1")); 01504 01505 01506 dexbutton = gtk_button_new_with_label ("Dex"); 01507 gtk_box_pack_start (GTK_BOX (hbox), dexbutton, TRUE, 01508 TRUE, 1); 01509 gtk_signal_connect_object (GTK_OBJECT (dexbutton), 01510 "clicked", 01511 GTK_SIGNAL_FUNC (sendstr), 01512 GINT_TO_POINTER ("2")); 01513 01514 conbutton = gtk_button_new_with_label ("Con"); 01515 gtk_box_pack_start (GTK_BOX (hbox), conbutton, TRUE, 01516 TRUE, 1); 01517 gtk_signal_connect_object (GTK_OBJECT (conbutton), 01518 "clicked", 01519 GTK_SIGNAL_FUNC (sendstr), 01520 GINT_TO_POINTER ("3")); 01521 01522 intbutton = gtk_button_new_with_label ("Int"); 01523 gtk_box_pack_start (GTK_BOX (hbox), intbutton, TRUE, 01524 TRUE, 1); 01525 gtk_signal_connect_object (GTK_OBJECT (intbutton), 01526 "clicked", 01527 GTK_SIGNAL_FUNC (sendstr), 01528 GINT_TO_POINTER ("4")); 01529 01530 wisbutton = gtk_button_new_with_label ("Wis"); 01531 gtk_box_pack_start (GTK_BOX (hbox), wisbutton, TRUE, 01532 TRUE, 1); 01533 gtk_signal_connect_object (GTK_OBJECT (wisbutton), 01534 "clicked", 01535 GTK_SIGNAL_FUNC (sendstr), 01536 GINT_TO_POINTER ("5")); 01537 01538 powbutton = gtk_button_new_with_label ("Pow"); 01539 gtk_box_pack_start (GTK_BOX (hbox), powbutton, TRUE, 01540 TRUE, 1); 01541 gtk_signal_connect_object (GTK_OBJECT (powbutton), 01542 "clicked", 01543 GTK_SIGNAL_FUNC (sendstr), 01544 GINT_TO_POINTER ("6")); 01545 01546 chabutton = gtk_button_new_with_label ("Cha"); 01547 gtk_box_pack_start (GTK_BOX (hbox), chabutton, TRUE, 01548 TRUE, 1); 01549 gtk_signal_connect_object (GTK_OBJECT (chabutton), 01550 "clicked", 01551 GTK_SIGNAL_FUNC (sendstr), 01552 GINT_TO_POINTER ("7")); 01553 01554 gtk_widget_show (strbutton); 01555 gtk_widget_show (dexbutton); 01556 gtk_widget_show (conbutton); 01557 gtk_widget_show (intbutton); 01558 gtk_widget_show (wisbutton); 01559 gtk_widget_show (powbutton); 01560 gtk_widget_show (chabutton); 01561 01562 01563 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01564 6); 01565 gtk_widget_show (hbox); 01566 01567 found = TRUE; 01568 continue; 01569 } 01570 01571 if (!strncmp (last_str, "Press `d'", 9)) 01572 { 01573 01574 01575 dialoglabel = gtk_label_new ("Choose a character."); 01576 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01577 TRUE, 6); 01578 gtk_widget_show (dialoglabel); 01579 01580 hbox = gtk_hbox_new (FALSE, 6); 01581 01582 yesbutton = gtk_button_new_with_label ("Show next"); 01583 gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE, 01584 TRUE, 6); 01585 gtk_signal_connect_object (GTK_OBJECT (yesbutton), 01586 "clicked", 01587 GTK_SIGNAL_FUNC (sendstr), 01588 GINT_TO_POINTER (" ")); 01589 01590 nobutton = gtk_button_new_with_label ("Keep this"); 01591 gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE, 01592 TRUE, 6); 01593 gtk_signal_connect_object (GTK_OBJECT (nobutton), 01594 "clicked", 01595 GTK_SIGNAL_FUNC (sendstr), 01596 GINT_TO_POINTER ("d")); 01597 01598 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01599 6); 01600 01601 gtk_widget_show (yesbutton); 01602 gtk_widget_show (nobutton); 01603 gtk_widget_show (hbox); 01604 01605 found = TRUE; 01606 continue; 01607 } 01608 01609 if (!strncmp (str, "Do you want to play", 18)) 01610 { 01611 01612 01613 dialoglabel = 01614 gtk_label_new ("Do you want to play again?"); 01615 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01616 TRUE, 6); 01617 gtk_widget_show (dialoglabel); 01618 01619 hbox = gtk_hbox_new (FALSE, 6); 01620 01621 yesbutton = gtk_button_new_with_label ("Play again"); 01622 gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE, 01623 TRUE, 6); 01624 gtk_signal_connect_object (GTK_OBJECT (yesbutton), 01625 "clicked", 01626 GTK_SIGNAL_FUNC (sendstr), 01627 GINT_TO_POINTER ("a")); 01628 01629 nobutton = gtk_button_new_with_label ("Quit"); 01630 gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE, 01631 TRUE, 6); 01632 gtk_signal_connect_object (GTK_OBJECT (nobutton), 01633 "clicked", 01634 GTK_SIGNAL_FUNC (sendstr), 01635 GINT_TO_POINTER ("q")); 01636 01637 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01638 6); 01639 01640 gtk_widget_show (yesbutton); 01641 gtk_widget_show (nobutton); 01642 gtk_widget_show (hbox); 01643 01644 found = TRUE; 01645 continue; 01646 } 01647 01648 if (!strncmp (str, "Are you sure you want", 21)) 01649 { 01650 01651 01652 dialoglabel = 01653 gtk_label_new ("Are you sure you want to quit?"); 01654 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01655 TRUE, 6); 01656 gtk_widget_show (dialoglabel); 01657 01658 hbox = gtk_hbox_new (FALSE, 6); 01659 01660 yesbutton = gtk_button_new_with_label ("Yes, quit"); 01661 gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE, 01662 TRUE, 6); 01663 gtk_signal_connect_object (GTK_OBJECT (yesbutton), 01664 "clicked", 01665 GTK_SIGNAL_FUNC (sendstr), 01666 GINT_TO_POINTER ("y")); 01667 01668 nobutton = gtk_button_new_with_label ("Don't quit"); 01669 gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE, 01670 TRUE, 6); 01671 gtk_signal_connect_object (GTK_OBJECT (nobutton), 01672 "clicked", 01673 GTK_SIGNAL_FUNC (sendstr), 01674 GINT_TO_POINTER ("n")); 01675 01676 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01677 6); 01678 01679 gtk_widget_show (yesbutton); 01680 gtk_widget_show (nobutton); 01681 gtk_widget_show (hbox); 01682 01683 found = TRUE; 01684 continue; 01685 } 01686 01687 if (!strcmp (last_str, "What is the password?")) 01688 { 01689 01690 dialoglabel = 01691 gtk_label_new ("What is the party password?"); 01692 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, 01693 FALSE, TRUE, 6); 01694 gtk_widget_show (dialoglabel); 01695 01696 hbox = gtk_hbox_new (FALSE, 6); 01697 dialogtext = gtk_entry_new (); 01698 gtk_entry_set_visibility (GTK_ENTRY (dialogtext), 01699 FALSE); 01700 gtk_signal_connect (GTK_OBJECT (dialogtext), 01701 "activate", 01702 GTK_SIGNAL_FUNC 01703 (dialog_callback), 01704 dialog_window); 01705 gtk_box_pack_start (GTK_BOX (hbox), dialogtext, 01706 TRUE, TRUE, 6); 01707 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, 01708 TRUE, 6); 01709 01710 gtk_widget_show (hbox); 01711 01712 gtk_widget_show (dialogtext); 01713 gtk_widget_grab_focus (dialogtext); 01714 found = TRUE; 01715 continue;; 01716 } 01717 01718 if (!found) 01719 { 01720 dialoglabel = gtk_label_new (str); 01721 gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE, 01722 TRUE, 6); 01723 gtk_widget_show (dialoglabel); 01724 01725 hbox = gtk_hbox_new (FALSE, 6); 01726 dialogtext = gtk_entry_new (); 01727 if (cpl.no_echo == 1) 01728 gtk_entry_set_visibility(GTK_ENTRY (dialogtext), FALSE); 01729 01730 gtk_signal_connect (GTK_OBJECT (dialogtext), "activate", 01731 GTK_SIGNAL_FUNC (dialog_callback), 01732 dialog_window); 01733 gtk_box_pack_start (GTK_BOX (hbox), dialogtext, TRUE, 01734 TRUE, 6); 01735 gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE, 01736 6); 01737 01738 gtk_widget_show (hbox); 01739 gtk_widget_show (dialogtext); 01740 gtk_widget_grab_focus (dialogtext); 01741 found = TRUE; 01742 continue; 01743 } 01744 } 01745 01746 /* Finished with the contents. */ 01747 01748 01749 gtk_widget_show (dbox); 01750 gtk_widget_show (dialog_window); 01751 } 01752 01753 } 01754 01755 /* draw_info adds a line to the info window. For speed reasons it will 01756 * automatically freeze the info window when adding text to it, set the 01757 * draw_info_freeze variable true and the actual drawing will take place 01758 * during the next do_timeout at which point it is unfrozen again. That way 01759 * we handle massive amounts of text addition with a single GUI event, which 01760 * results in a serious speed improvement for slow client machines (and 01761 * above all it avoids a GUI lockup when the client becomes congested with 01762 * updates (which is often when you're in the middle of fighting something 01763 * serious and not a good time to get slow reaction time)). 01764 * 01765 * MSW 2001-05-25: The removal of input from the text windows should 01766 * work, and in fact does about 90% of the time. But that 10% it 01767 * doesn't, the client crashes. The error itself is in the gtk library, 01768 * to hopefully they will fix it someday. The reason to do this is 01769 * to keep these buffers a reasonable size so that performance stays 01770 * good - otherwise, performance slowly degrades. 01771 */ 01772 01773 void draw_info(const char *str, int color) { 01774 int ncolor = color; 01775 char timestamp[11]=""; 01776 01777 if (ncolor==NDI_WHITE) { 01778 ncolor=NDI_BLACK; 01779 } 01780 if (use_config[CONFIG_TIMESTAMP] && color != NDI_BLACK) { 01781 struct tm *now; 01782 time_t currenttime = time(0); 01783 now = localtime(¤ttime); 01784 strftime(timestamp, 10, "%I:%M: ", now); 01785 } 01786 strcpy (last_str, str); 01787 if (use_config[CONFIG_SPLITINFO] && color != NDI_BLACK) { 01788 if (!draw_info_freeze2){ 01789 gtk_text_freeze (GTK_TEXT (gtkwin_info_text2)); 01790 draw_info_freeze2=TRUE; 01791 } 01792 if (use_config[CONFIG_TRIMINFO]) { 01793 info2_num_chars += strlen(str) + 1; 01794 /* Limit size of scrollback buffer. To be more efficient, delete a good 01795 * blob (5000) characters at a time - in that way, there will be some 01796 * time between needing to delete. 01797 */ 01798 if (info2_num_chars > info2_max_chars ) { 01799 gtk_text_set_point(GTK_TEXT(gtkwin_info_text2),0); 01800 gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text2), (info2_num_chars - info2_max_chars) + 5000); 01801 info2_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text2)); 01802 gtk_text_set_point(GTK_TEXT(gtkwin_info_text2), info2_num_chars); 01803 LOG(LOG_INFO,"gtk::draw_info","reduced output buffer2 to %d chars", info1_num_chars); 01804 } 01805 } 01806 if (use_config[CONFIG_TIMESTAMP]) 01807 gtk_text_insert(GTK_TEXT (gtkwin_info_text2), NULL, &root_color[NDI_GREY], NULL, timestamp, -1); 01808 gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, str, -1); 01809 gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, "\n" , -1); 01810 01811 } else { 01812 /* All notes in the above section apply here also */ 01813 if (!draw_info_freeze1){ 01814 gtk_text_freeze (GTK_TEXT (gtkwin_info_text)); 01815 draw_info_freeze1=TRUE; 01816 } 01817 if (use_config[CONFIG_TRIMINFO]) { 01818 info1_num_chars += strlen(str) + 1; 01819 if (info1_num_chars > info1_max_chars ) { 01820 #if 1 01821 int to_delete = (info1_num_chars - info1_max_chars) + 5000; 01822 /* Delete on newline boundaries */ 01823 while (GTK_TEXT_INDEX(GTK_TEXT(gtkwin_info_text), to_delete)!='\n') 01824 to_delete++; 01825 gtk_text_set_point(GTK_TEXT(gtkwin_info_text),0); 01826 gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text), to_delete); 01827 info1_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text)); 01828 gtk_text_set_point(GTK_TEXT(gtkwin_info_text), info1_num_chars); 01829 LOG(LOG_INFO,"gtk::draw_info", 01830 "trim_info_window, deleted %d characters, %d remaining", 01831 to_delete, info1_num_chars); 01832 #else 01833 /* This works, so it is possible to completely clear the window */ 01834 info1_num_chars = gtk_text_get_length(GTK_TEXT (gtkwin_info_text)); 01835 gtk_text_set_point(GTK_TEXT (gtkwin_info_text), 0); 01836 gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text), info1_num_chars ); 01837 gtk_text_thaw (GTK_TEXT (gtkwin_info_text)); 01838 info1_num_chars=0; 01839 #endif 01840 } 01841 01842 } 01843 if (use_config[CONFIG_TIMESTAMP]) 01844 gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[NDI_GREY], NULL, timestamp, -1); 01845 gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, str , -1); 01846 gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, "\n" , -1); 01847 } 01848 } 01849 01850 01851 void draw_color_info(int colr, const char *buf){ 01852 draw_info(buf,colr); 01853 } 01854 01855 /*********************************************************************** 01856 * 01857 * Stats window functions follow 01858 * 01859 ***********************************************************************/ 01860 01861 static int get_stats_display(GtkWidget *frame) { 01862 GtkWidget *stats_vbox; 01863 GtkWidget *stats_box_1; 01864 GtkWidget *stats_box_2; 01865 GtkWidget *stats_box_4; 01866 GtkWidget *stats_box_5; 01867 GtkWidget *stats_box_6; 01868 GtkWidget *stats_box_7; 01869 GtkWidget *table; 01870 int i,x,y; 01871 01872 01873 stats_vbox = gtk_vbox_new (FALSE, 0); 01874 01875 /* 1st row - Player name */ 01876 stats_box_1 = gtk_hbox_new (FALSE, 0); 01877 01878 statwindow.playername = gtk_label_new("Player: "); 01879 gtk_box_pack_start (GTK_BOX (stats_box_1), statwindow.playername, FALSE, FALSE, 5); 01880 gtk_widget_show (statwindow.playername); 01881 01882 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_1, FALSE, FALSE, 0); 01883 gtk_widget_show (stats_box_1); 01884 01885 /* 2nd row - score and level */ 01886 stats_box_2 = gtk_hbox_new (FALSE, 0); 01887 statwindow.score = gtk_label_new("Score: 0"); 01888 gtk_box_pack_start (GTK_BOX (stats_box_2), statwindow.score, FALSE, FALSE, 5); 01889 gtk_widget_show (statwindow.score); 01890 01891 statwindow.level = gtk_label_new("Level: 0"); 01892 gtk_box_pack_start (GTK_BOX (stats_box_2), statwindow.level, FALSE, FALSE, 5); 01893 gtk_widget_show (statwindow.level); 01894 01895 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_2, FALSE, FALSE, 0); 01896 gtk_widget_show (stats_box_2); 01897 01898 01899 /* 4th row (really the thrid) - the stats - str, dex, con, etc */ 01900 stats_box_4 = gtk_hbox_new (FALSE, 0); 01901 01902 statwindow.Str = gtk_label_new("S 0"); 01903 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Str, FALSE, FALSE, 5); 01904 gtk_widget_show (statwindow.Str); 01905 01906 statwindow.Dex = gtk_label_new("D 0"); 01907 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Dex, FALSE, FALSE, 5); 01908 gtk_widget_show (statwindow.Dex); 01909 01910 statwindow.Con = gtk_label_new("Co 0"); 01911 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Con, FALSE, FALSE, 5); 01912 gtk_widget_show (statwindow.Con); 01913 01914 statwindow.Int = gtk_label_new("I 0"); 01915 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Int, FALSE, FALSE, 5); 01916 gtk_widget_show (statwindow.Int); 01917 01918 statwindow.Wis = gtk_label_new("W 0"); 01919 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Wis, FALSE, FALSE, 5); 01920 gtk_widget_show (statwindow.Wis); 01921 01922 statwindow.Pow = gtk_label_new("P 0"); 01923 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Pow, FALSE, FALSE, 5); 01924 gtk_widget_show (statwindow.Pow); 01925 01926 statwindow.Cha = gtk_label_new("Ch 0"); 01927 gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Cha, FALSE, FALSE, 5); 01928 gtk_widget_show (statwindow.Cha); 01929 01930 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_4, FALSE, FALSE, 0); 01931 gtk_widget_show (stats_box_4); 01932 01933 /* 5th row wc, dam, ac, armor*/ 01934 01935 stats_box_5 = gtk_hbox_new (FALSE, 0); 01936 01937 statwindow.wc = gtk_label_new("Wc: 0"); 01938 gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.wc, FALSE, FALSE, 5); 01939 gtk_widget_show (statwindow.wc); 01940 01941 statwindow.dam = gtk_label_new("Dam: 0"); 01942 gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.dam, FALSE, FALSE, 5); 01943 gtk_widget_show (statwindow.dam); 01944 01945 statwindow.ac = gtk_label_new("Ac: 0"); 01946 gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.ac, FALSE, FALSE, 5); 01947 gtk_widget_show (statwindow.ac); 01948 01949 statwindow.armor = gtk_label_new("Armor: 0"); 01950 gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.armor, FALSE, FALSE, 5); 01951 gtk_widget_show (statwindow.armor); 01952 01953 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_5, FALSE, FALSE, 0); 01954 gtk_widget_show (stats_box_5); 01955 01956 /* 6th row speed and weapon speed */ 01957 01958 stats_box_6 = gtk_hbox_new (FALSE, 0); 01959 01960 statwindow.speed = gtk_label_new("Speed: 0"); 01961 gtk_box_pack_start (GTK_BOX (stats_box_6), statwindow.speed, FALSE, FALSE, 5); 01962 gtk_widget_show (statwindow.speed); 01963 01964 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_6, FALSE, FALSE, 0); 01965 gtk_widget_show (stats_box_6); 01966 01967 /* 7th row - range */ 01968 01969 stats_box_7 = gtk_hbox_new (FALSE, 0); 01970 01971 statwindow.skill = gtk_label_new("Skill: 0"); 01972 gtk_box_pack_start (GTK_BOX (stats_box_7), statwindow.skill, FALSE, FALSE, 5); 01973 gtk_widget_show (statwindow.skill); 01974 gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_7, FALSE, FALSE, 0); 01975 gtk_widget_show (stats_box_7); 01976 01977 01978 /* Start of experience display - we do it in a 4 x 4 array. Use a table 01979 * so that spacing is uniform - this should look better. 01980 * Change it so we use one field for the name, and the other for exp - 01981 * in this way, the values line up better. 01982 */ 01983 01984 table = gtk_table_new (4, 4, FALSE); 01985 x=0; 01986 y=0; 01987 /* This is all the same - we just pack it in different places */ 01988 for (i=0; i<MAX_SKILL*2; i++) { 01989 statwindow.skill_exp[i] = gtk_label_new(""); 01990 gtk_table_attach(GTK_TABLE(table), statwindow.skill_exp[i], x, x+1, y, y+1, GTK_FILL | GTK_EXPAND, 0, 10, 0); 01991 x++; 01992 if (x==4) { x=0; y++; } 01993 gtk_widget_show(statwindow.skill_exp[i]); 01994 } 01995 skill_scrolled_window = gtk_scrolled_window_new (NULL, NULL); 01996 gtk_container_set_border_width (GTK_CONTAINER (res_scrolled_window), 0); 01997 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (skill_scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 01998 gtk_box_pack_start(GTK_BOX(stats_vbox), skill_scrolled_window, TRUE, TRUE, 0); 01999 gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (skill_scrolled_window), table); 02000 02001 gtk_widget_show(table); 02002 02003 gtk_container_add (GTK_CONTAINER (frame), stats_vbox); 02004 gtk_widget_show (stats_vbox); 02005 gtk_widget_show (skill_scrolled_window); 02006 02007 return 0; 02008 } 02009 02010 /* This draws the stats window. If redraw is true, it means 02011 * we need to redraw the entire thing, and not just do an 02012 * updated. 02013 */ 02014 02015 void draw_stats(int redraw) { 02016 static Stats last_stats; 02017 static char last_name[MAX_BUF]="", last_range[MAX_BUF]=""; 02018 static int init_before=0, lastbeep=0, max_drawn_skill=0; 02019 02020 float weap_sp; 02021 char buff[MAX_BUF]; 02022 int i, on_skill; 02023 02024 if (!init_before) { 02025 init_before=1; 02026 memset(&last_stats, 0, sizeof(Stats)); 02027 } 02028 02029 if (updatelock < 25) { 02030 updatelock++; 02031 if (strcmp(cpl.title, last_name) || redraw) { 02032 strcpy(last_name,cpl.title); 02033 strcpy(buff,cpl.title); 02034 gtk_label_set (GTK_LABEL(statwindow.playername), cpl.title); 02035 gtk_widget_draw (statwindow.playername, NULL); 02036 } 02037 02038 if(redraw || cpl.stats.exp!=last_stats.exp) { 02039 last_stats.exp = cpl.stats.exp; 02040 sprintf(buff,"Score: %5" FMT64 ,cpl.stats.exp); 02041 02042 gtk_label_set (GTK_LABEL(statwindow.score), buff); 02043 gtk_widget_draw (statwindow.score, NULL); 02044 } 02045 02046 if(redraw || cpl.stats.level!=last_stats.level) { 02047 last_stats.level = cpl.stats.level; 02048 sprintf(buff,"Level: %d",cpl.stats.level); 02049 gtk_label_set (GTK_LABEL(statwindow.level), buff); 02050 gtk_widget_draw (statwindow.level, NULL); 02051 } 02052 02053 if(redraw || 02054 cpl.stats.hp!=last_stats.hp || cpl.stats.maxhp!=last_stats.maxhp) { 02055 last_stats.hp=cpl.stats.hp; 02056 last_stats.maxhp=cpl.stats.maxhp; 02057 sprintf(buff,"Hp: %d/%d",cpl.stats.hp, cpl.stats.maxhp); 02058 gtk_label_set (GTK_LABEL(statwindow.hp), buff); 02059 gtk_widget_draw (statwindow.hp, NULL); 02060 } 02061 02062 if(redraw || 02063 cpl.stats.sp!=last_stats.sp || cpl.stats.maxsp!=last_stats.maxsp) { 02064 last_stats.sp=cpl.stats.sp; 02065 last_stats.maxsp=cpl.stats.maxsp; 02066 sprintf(buff,"Sp: %d/%d",cpl.stats.sp, cpl.stats.maxsp); 02067 gtk_label_set (GTK_LABEL(statwindow.sp), buff); 02068 gtk_widget_draw (statwindow.sp, NULL); 02069 } 02070 02071 if(redraw || 02072 cpl.stats.grace!=last_stats.grace || cpl.stats.maxgrace!=last_stats.maxgrace) { 02073 last_stats.grace=cpl.stats.grace; 02074 last_stats.maxgrace=cpl.stats.maxgrace; 02075 sprintf(buff,"Gr: %d/%d",cpl.stats.grace, cpl.stats.maxgrace); 02076 gtk_label_set (GTK_LABEL(statwindow.gr), buff); 02077 gtk_widget_draw (statwindow.gr, NULL); 02078 } 02079 02080 if(redraw || cpl.stats.Str!=last_stats.Str) { 02081 last_stats.Str=cpl.stats.Str; 02082 sprintf(buff,"S%2d",cpl.stats.Str); 02083 gtk_label_set (GTK_LABEL(statwindow.Str), buff); 02084 gtk_widget_draw (statwindow.Str, NULL); 02085 } 02086 02087 if(redraw || cpl.stats.Dex!=last_stats.Dex) { 02088 last_stats.Dex=cpl.stats.Dex; 02089 sprintf(buff,"D%2d",cpl.stats.Dex); 02090 gtk_label_set (GTK_LABEL(statwindow.Dex), buff); 02091 gtk_widget_draw (statwindow.Dex, NULL); 02092 } 02093 02094 if(redraw || cpl.stats.Con!=last_stats.Con) { 02095 last_stats.Con=cpl.stats.Con; 02096 sprintf(buff,"Co%2d",cpl.stats.Con); 02097 gtk_label_set (GTK_LABEL(statwindow.Con), buff); 02098 gtk_widget_draw (statwindow.Con, NULL); 02099 } 02100 02101 if(redraw || cpl.stats.Int!=last_stats.Int) { 02102 last_stats.Int=cpl.stats.Int; 02103 sprintf(buff,"I%2d",cpl.stats.Int); 02104 gtk_label_set (GTK_LABEL(statwindow.Int), buff); 02105 gtk_widget_draw (statwindow.Int, NULL); 02106 } 02107 02108 if(redraw || cpl.stats.Wis!=last_stats.Wis) { 02109 last_stats.Wis=cpl.stats.Wis; 02110 sprintf(buff,"W%2d",cpl.stats.Wis); 02111 gtk_label_set (GTK_LABEL(statwindow.Wis), buff); 02112 gtk_widget_draw (statwindow.Wis, NULL); 02113 } 02114 02115 if(redraw || cpl.stats.Pow!=last_stats.Pow) { 02116 last_stats.Pow=cpl.stats.Pow; 02117 sprintf(buff,"P%2d",cpl.stats.Pow); 02118 gtk_label_set (GTK_LABEL(statwindow.Pow), buff); 02119 gtk_widget_draw (statwindow.Pow, NULL); 02120 } 02121 02122 if(redraw || cpl.stats.Cha!=last_stats.Cha) { 02123 last_stats.Cha=cpl.stats.Cha; 02124 sprintf(buff,"Ch%2d",cpl.stats.Cha); 02125 gtk_label_set (GTK_LABEL(statwindow.Cha), buff); 02126 gtk_widget_draw (statwindow.Cha, NULL); 02127 } 02128 02129 if(redraw || cpl.stats.wc!=last_stats.wc) { 02130 last_stats.wc=cpl.stats.wc; 02131 sprintf(buff,"Wc%3d",cpl.stats.wc); 02132 gtk_label_set (GTK_LABEL(statwindow.wc), buff); 02133 gtk_widget_draw (statwindow.wc, NULL); 02134 } 02135 02136 if(redraw || cpl.stats.dam!=last_stats.dam) { 02137 last_stats.dam=cpl.stats.dam; 02138 sprintf(buff,"Dam%3d",cpl.stats.dam); 02139 gtk_label_set (GTK_LABEL(statwindow.dam), buff); 02140 gtk_widget_draw (statwindow.dam, NULL); 02141 } 02142 02143 if(redraw || cpl.stats.ac!=last_stats.ac) { 02144 last_stats.ac=cpl.stats.ac; 02145 sprintf(buff,"Ac%3d",cpl.stats.ac); 02146 gtk_label_set (GTK_LABEL(statwindow.ac), buff); 02147 gtk_widget_draw (statwindow.ac, NULL); 02148 } 02149 02150 if(redraw || cpl.stats.resists[0]!=last_stats.resists[0]) { 02151 last_stats.resists[0]=cpl.stats.resists[0]; 02152 sprintf(buff,"Arm%3d",cpl.stats.resists[0]); 02153 gtk_label_set (GTK_LABEL(statwindow.armor), buff); 02154 gtk_widget_draw (statwindow.armor, NULL); 02155 } 02156 02157 if(redraw || cpl.stats.speed!=last_stats.speed || 02158 cpl.stats.weapon_sp != last_stats.weapon_sp) { 02159 last_stats.speed=cpl.stats.speed; 02160 last_stats.weapon_sp=cpl.stats.weapon_sp; 02161 weap_sp = (float) cpl.stats.speed/((float)cpl.stats.weapon_sp); 02162 sprintf(buff,"Speed: %3.2f (%1.2f)",(float)cpl.stats.speed/FLOAT_MULTF,weap_sp); 02163 gtk_label_set (GTK_LABEL(statwindow.speed), buff); 02164 gtk_widget_draw (statwindow.speed, NULL); 02165 } 02166 02167 if(redraw || cpl.stats.food!=last_stats.food) { 02168 last_stats.food=cpl.stats.food; 02169 sprintf(buff,"Food: %3d",cpl.stats.food); 02170 gtk_label_set (GTK_LABEL(statwindow.food), buff); 02171 gtk_widget_draw (statwindow.food, NULL); 02172 if (use_config[CONFIG_FOODBEEP] && (cpl.stats.food%4==3) && (cpl.stats.food < 200)) 02173 #ifndef WIN32 02174 XBell(GDK_DISPLAY(), 0); 02175 #else 02176 gdk_beep( ); 02177 #endif 02178 } else if (use_config[CONFIG_FOODBEEP] && cpl.stats.food == 0 && ++lastbeep == 5) { 02179 lastbeep = 0; 02180 #ifndef WIN32 02181 XBell(GDK_DISPLAY(), 0); 02182 #else 02183 gdk_beep( ); 02184 #endif 02185 } 02186 02187 if(redraw || strcmp(cpl.range, last_range)) { 02188 strcpy(last_range, cpl.range); 02189 gtk_label_set (GTK_LABEL(statwindow.skill), cpl.range); 02190 gtk_widget_draw (statwindow.skill, NULL); 02191 } 02192 on_skill=0; 02193 for (i=0; i<MAX_SKILL; i++) { 02194 /* Drawing a particular skill entry is tricky - only draw if 02195 * different, and only draw if we have a name for the skill 02196 * and the player has some exp in the skill - don't draw 02197 * all 30 skills for no reason. 02198 */ 02199 if ((redraw || cpl.stats.skill_exp[i] != last_stats.skill_exp[i]) && 02200 skill_names[i] && cpl.stats.skill_level[i]) { 02201 gtk_label_set(GTK_LABEL(statwindow.skill_exp[on_skill++]), skill_names[i]); 02202 sprintf(buff,"%" FMT64 " (%d)", cpl.stats.skill_exp[i], cpl.stats.skill_level[i]); 02203 gtk_label_set(GTK_LABEL(statwindow.skill_exp[on_skill++]), buff); 02204 last_stats.skill_level[i] = cpl.stats.skill_level[i]; 02205 last_stats.skill_exp[i] = cpl.stats.skill_exp[i]; 02206 } else if (cpl.stats.skill_level[i]) { 02207 /* Don't need to draw the skill, but need to update the position 02208 * of where to draw the next one. 02209 */ 02210 on_skill+=2; 02211 } 02212 } 02213 /* Since the number of skills we draw come and go, basically we want 02214 * to erase any extra. This shows up when switching characters, eg, character 02215 * #1 knows 10 skills, #2 knows 5 - need to erase those 5 extra. 02216 */ 02217 if (on_skill < max_drawn_skill) { 02218 int k; 02219 02220 for (k = on_skill; k <= max_drawn_skill; k++) 02221 gtk_label_set(GTK_LABEL(statwindow.skill_exp[k]), ""); 02222 } 02223 max_drawn_skill = on_skill; 02224 } /* updatelock < 25 */ 02225 } 02226 02227 02228 /*********************************************************************** 02229 * 02230 * Handles the message window 02231 * 02232 ***********************************************************************/ 02233 02234 02235 static void create_stat_bar(GtkWidget *mtable, gint row, const gchar *label, gint bar, GtkWidget **plabel) { 02236 /* GtkWidget *plabel;*/ 02237 02238 *plabel = gtk_label_new (label); 02239 gtk_table_attach (GTK_TABLE (mtable), *plabel, 0, 1, row, row+1,/*GTK_FILL |*/ GTK_EXPAND,GTK_FILL | GTK_EXPAND,0,0); 02240 gtk_widget_show (*plabel); 02241 02242 vitals[bar].bar = gtk_progress_bar_new (); 02243 gtk_table_attach(GTK_TABLE(mtable), vitals[bar].bar, 0,1,row+1,row+2,GTK_FILL | GTK_EXPAND, 0 ,3,0); 02244 gtk_widget_set_usize (vitals[bar].bar,100,15); 02245 02246 02247 gtk_widget_show (vitals[bar].bar); 02248 02249 02250 02251 vitals[bar].state=1; 02252 02253 vitals[bar].style[0] = gtk_style_new (); 02254 vitals[bar].style[0]->bg[GTK_STATE_PRELIGHT] = gdk_green; 02255 gtk_widget_set_style (vitals[bar].bar, vitals[bar].style[0]); 02256 vitals[bar].style[1] = gtk_style_new (); 02257 vitals[bar].style[1]->bg[GTK_STATE_PRELIGHT] = gdk_red; 02258 02259 } 02260 02261 /* This is used when going from gradiated color stat bars back 02262 * to the normal - we need to reset the colors. 02263 */ 02264 void reset_stat_bars(void) { 02265 int i; 02266 02267 for (i=0; i<4; i++) { 02268 vitals[i].style[0]->bg[GTK_STATE_PRELIGHT] = gdk_green; 02269 vitals[i].style[1]->bg[GTK_STATE_PRELIGHT] = gdk_red; 02270 /* Need to do this double switch so that the color gets updated. Otherwise, 02271 * if we are currently using style[0] to draw, the update above won't 02272 * have any effect. 02273 */ 02274 gtk_widget_set_style(vitals[i].bar, vitals[i].style[1]); 02275 gtk_widget_set_style(vitals[i].bar, vitals[i].style[0]); 02276 vitals[i].state = 0; 02277 02278 } 02279 draw_message_window(1); 02280 } 02281 02282 static int get_message_display(GtkWidget *frame) { 02283 GtkWidget *mtable; 02284 GtkWidget *vbox; 02285 GtkWidget *res_mainbox; 02286 GtkWidget *reswindow; 02287 02288 /* Initialize the main hbox */ 02289 res_mainbox = gtk_hbox_new (TRUE,0); 02290 gtk_container_add (GTK_CONTAINER(frame), res_mainbox); 02291 02292 /* stat bar part - start */ 02293 02294 /* Initialize the vbox for the stat bars (Hp,Mana,Grace,Food) 02295 * and pack it into the main hbox 02296 */ 02297 vbox = gtk_vbox_new (FALSE, 0); 02298 gtk_box_pack_start (GTK_BOX(res_mainbox), vbox, FALSE, TRUE, 0); 02299 02300 /* Initialize the table and pack this into the vbox */ 02301 mtable = gtk_table_new (2,4,FALSE); 02302 gtk_box_pack_start (GTK_BOX(vbox),mtable,FALSE,FALSE,0); 02303 02304 /* Create the stat bars and place them in the table */ 02305 create_stat_bar (mtable, 1,"Hp: 0",0, &statwindow.hp); 02306 create_stat_bar (mtable, 3,"Mana: 0",1, &statwindow.sp); 02307 create_stat_bar (mtable, 5,"Grace: 0",2, &statwindow.gr); 02308 create_stat_bar (mtable, 7,"Food: 0",3, &statwindow.food); 02309 02310 /* Stat bar part - end */ 02311 02312 02313 /* Resistances table part - start */ 02314 02315 /* Initialize the hbox for the resistances table */ 02316 reswindow = gtk_hbox_new (TRUE, 0); 02317 gtk_box_pack_start(GTK_BOX(res_mainbox), reswindow, FALSE, TRUE, 0); 02318 02319 /* Create the resistance table*/ 02320 restable = gtk_table_new (4,12,FALSE); 02321 02322 /* Packing the restable in a scrollable window*/ 02323 res_scrolled_window = gtk_scrolled_window_new (NULL, NULL); 02324 gtk_container_set_border_width (GTK_CONTAINER (res_scrolled_window), 0); 02325 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (res_scrolled_window), 02326 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 02327 gtk_box_pack_start(GTK_BOX(reswindow), res_scrolled_window, TRUE, TRUE, 0); 02328 gtk_widget_show (res_scrolled_window); 02329 gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (res_scrolled_window), restable); 02330 02331 /* Finally, draw the resistances table */ 02332 resize_resistance_table(use_config[CONFIG_RESISTS]); 02333 02334 /* Resistances table part - end */ 02335 02336 /* Now showing all not already showed widgets */ 02337 gtk_widget_show (res_mainbox); 02338 gtk_widget_show (reswindow); 02339 gtk_widget_show (restable); 02340 gtk_widget_show (mtable); 02341 gtk_widget_show (vbox); 02342 return 0; 02343 } 02344 02345 /* This handles layout of the resistance window. 02346 * We end up just removing (and thus freeing) all the data and 02347 * then create new entries. This keeps things simpler, because 02348 * in basic mode, not all the resist[] widgets are attached, 02349 */ 02350 void resize_resistance_table(int resists_show) { 02351 int i, left=0, right=0; 02352 02353 while (GTK_TABLE(restable)->children) { 02354 GtkTableChild *child; 02355 child = GTK_TABLE(restable)->children->data; 02356 02357 gtk_container_remove(GTK_CONTAINER(restable), 02358 child->widget); 02359 } 02360 02361 /* Initialize labels for all modes of CONFIG_RESISTS */ 02362 fire_label = gtk_label_new (" "); 02363 run_label = gtk_label_new (" "); 02364 02365 /* Place labels for dual-column mode of CONFIG_RESISTS */ 02366 if (resists_show) { 02367 gtk_table_resize(GTK_TABLE(restable), 4,12); 02368 gtk_table_attach (GTK_TABLE(restable), fire_label, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02369 gtk_table_attach (GTK_TABLE(restable), run_label, 3, 4, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02370 } 02371 else { /* Single column mode */ 02372 gtk_table_resize(GTK_TABLE(restable), 2,24); 02373 gtk_table_attach (GTK_TABLE(restable), fire_label, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02374 gtk_table_attach (GTK_TABLE(restable), run_label, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02375 } 02376 /* Show labels for all modes of CONFIG_RESISTS */ 02377 gtk_widget_show (fire_label); 02378 gtk_widget_show (run_label); 02379 /* Make and place labels for showing the resistances - start */ 02380 02381 for (i=0; i< NUM_RESISTS; i++) { 02382 resists[i] = gtk_label_new(" "); 02383 02384 /* Place the labels for dual columns in the table restable */ 02385 if (resists_show) { 02386 if ((i/2)*2 != i) { 02387 left++; 02388 gtk_table_attach (GTK_TABLE(restable), resists[i], 1, 2, 3+left, 4+left, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02389 } else { 02390 right++; 02391 gtk_table_attach (GTK_TABLE(restable), resists[i], 3, 4, 3+right, 4+right, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02392 } 02393 gtk_widget_show (resists[i]); 02394 } 02395 else { /* Single column style */ 02396 gtk_table_attach (GTK_TABLE(restable), resists[i], 0, 2, 3+i, 4+i, GTK_FILL | GTK_EXPAND, 0, 0, 0); 02397 gtk_widget_show (resists[i]); 02398 } 02399 } 02400 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (res_scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 02401 } 02402 02403 static void draw_stat_bar(int bar_pos, float bar, int is_alert) 02404 { 02405 if (use_config[CONFIG_GRAD_COLOR]) { 02406 /* In this mode, the color of the stat bar were go between red and green 02407 * in a gradual style. This, at 50% of the value, the stat bar will be 02408 * drawn in yellow. Pure fluff I know. 02409 */ 02410 int nstyle; 02411 GdkColor ncolor; 02412 /* We need to figure out what style to use. We can't call gtk_widget_set_style 02413 * on the widget currently in use - doing so results in no effect. 02414 * 53247 is float value of 0xcfff, which is the value used in the gdk_red 02415 * and gdk_green values. We double the values, so that it scales properly - 02416 * at .5, it then matches 53247, so the scaling appears proper. 02417 */ 02418 if (gtk_widget_get_style(vitals[bar_pos].bar) == vitals[bar_pos].style[0]) nstyle=1; 02419 else nstyle=0; 02420 /* We are 'supercharged' - scale to max of 2.0 for pure blue */ 02421 if (bar > 1.0) { 02422 if (bar>2.0) bar=2.0; /* Doesn't affect display, just are calculations */ 02423 ncolor.blue = 65535.0 * (bar - 1.0); 02424 ncolor.green = 53247.0 * (2.0 - bar); 02425 ncolor.red = 0; 02426 bar=1.0; 02427 } else { 02428 /* Use 0.5 as the adjustment - basically, if greater than 0.5, 02429 * we have pure green with lesser amounts of red. If less than 02430 * 0.5, we have pure red with lesser amounts of green. 02431 */ 02432 if (bar < 0.0) bar=0.0; /* Like above, doesn't affect display */ 02433 if (bar >= 0.5) ncolor.green = 0xcfff; 02434 else ncolor.green = 106494.0 * bar; 02435 if (bar <= 0.5) ncolor.red = 0xcfff; 02436 else ncolor.red = 106494.0 * (1.0 - bar); 02437 ncolor.blue = 0; 02438 } 02439 vitals[bar_pos].style[nstyle]->bg[GTK_STATE_PRELIGHT] = ncolor; 02440 gtk_widget_set_style(vitals[bar_pos].bar, vitals[bar_pos].style[nstyle]); 02441 vitals[bar_pos].state=is_alert; 02442 } else { 02443 if (bar>1.0) bar=1.0; 02444 if (is_alert) is_alert=1; /* Safety check */ 02445 if (vitals[bar_pos].state!=is_alert) { 02446 gtk_widget_set_style (vitals[bar_pos].bar, vitals[bar_pos].style[is_alert]); 02447 vitals[bar_pos].state=is_alert; 02448 } 02449 } 02450 gtk_progress_bar_update (GTK_PROGRESS_BAR (vitals[bar_pos].bar),bar ); 02451 gtk_widget_draw (vitals[bar_pos].bar, NULL); 02452 } 02453 02454 /* This updates the status bars. If redraw, then redraw them 02455 * even if they have not changed 02456 */ 02457 02458 void draw_message_window(int redraw) { 02459 float bar; 02460 int is_alert,flags; 02461 static uint16 scrollsize_hp=0, scrollsize_sp=0, scrollsize_food=0, 02462 scrollsize_grace=0; 02463 static uint8 scrollhp_alert=FALSE, scrollsp_alert=FALSE, 02464 scrollfood_alert=FALSE, scrollgrace_alert=FALSE; 02465 02466 if (updatelock < 25) { 02467 updatelock++; 02468 /* Draw hp bar */ 02469 if(cpl.stats.maxhp>0) 02470 { 02471 bar=(float)cpl.stats.hp/cpl.stats.maxhp; 02472 if(bar<=0) 02473 bar=(float)0.01; 02474 is_alert=(cpl.stats.hp <= cpl.stats.maxhp/4); 02475 } 02476 else 02477 { 02478 bar=(float)0.01; 02479 is_alert=0; 02480 } 02481 02482 if (redraw || scrollsize_hp!=bar || scrollhp_alert!=is_alert) 02483 draw_stat_bar(0, bar, is_alert); 02484 02485 scrollsize_hp=bar; 02486 scrollhp_alert=is_alert; 02487 02488 /* Draw sp bar. Let draw_stats_bar handle high values */ 02489 bar=(float)cpl.stats.sp/cpl.stats.maxsp; 02490 if(bar<=0) 02491 bar=(float)0.01; 02492 02493 is_alert=(cpl.stats.sp <= cpl.stats.maxsp/4); 02494 02495 if (redraw || scrollsize_sp!=bar || scrollsp_alert!=is_alert) 02496 draw_stat_bar(1, bar, is_alert); 02497 02498 scrollsize_sp=bar; 02499 scrollsp_alert=is_alert; 02500 02501 /* Draw grace bar. Grace can go above max or below min */ 02502 bar=(float)cpl.stats.grace/cpl.stats.maxgrace; 02503 if(bar<=0) 02504 bar=(float)0.01; 02505 02506 is_alert=(cpl.stats.grace <= cpl.stats.maxgrace/4); 02507 02508 if (redraw || scrollsize_grace!=bar || scrollgrace_alert!=is_alert) 02509 draw_stat_bar(2, bar, is_alert); 02510 02511 scrollsize_grace=bar; 02512 scrollgrace_alert=is_alert; 02513 02514 /* Draw food bar */ 02515 bar=(float)cpl.stats.food/999; 02516 if(bar<=0) 02517 bar=(float)0.01; 02518 is_alert=(cpl.stats.food <= 999/4); 02519 02520 if (redraw || scrollsize_food!=bar || scrollfood_alert!=is_alert) 02521 draw_stat_bar(3, bar, is_alert); 02522 02523 scrollsize_food=bar; 02524 scrollfood_alert=is_alert; 02525 02526 flags = cpl.stats.flags; 02527 02528 if (redraw || cpl.stats.resist_change) { 02529 int i,j=0; 02530 char buf[40]; 02531 02532 cpl.stats.resist_change=0; 02533 for (i=0; i<NUM_RESISTS; i++) { 02534 if (cpl.stats.resists[i]) { 02535 sprintf(buf,"%-10s %+4d", 02536 resists_name[i], cpl.stats.resists[i]); 02537 gtk_label_set(GTK_LABEL(resists[j]), buf); 02538 gtk_widget_draw(resists[j], NULL); 02539 j++; 02540 if (j >= NUM_RESISTS) break; 02541 } 02542 } 02543 /* Erase old/unused resistances */ 02544 while (j<NUM_RESISTS) { 02545 gtk_label_set(GTK_LABEL(resists[j]), " "); 02546 gtk_widget_draw(resists[j], NULL); 02547 j++; 02548 } 02549 } /* if we draw the resists */ 02550 } 02551 else { 02552 /* printf ("WARNING -- RACE. Frozen updates until updatelock is cleared!\n");*/ 02553 } 02554 } 02555 02556 02557 02558 02559 02560 02561 02562 /**************************************************************************** 02563 * 02564 * Dialogue boxes and the menus that raise them. 02565 * 02566 ****************************************************************************/ 02567 02568 static void aboutdialog(GtkWidget *widget) { 02569 #include "help/about.h" 02570 GtkWidget *vbox; 02571 GtkWidget *hbox; 02572 GtkWidget *aboutlabel; 02573 GtkWidget *vscrollbar; 02574 GtkWidget *aboutbutton; 02575 GtkWidget *aboutgtkpixmap; 02576 GdkPixmap *aboutgdkpixmap; 02577 GdkBitmap *aboutgdkmask; 02578 02579 GtkStyle *style; 02580 02581 if(!gtkwin_about) { 02582 02583 gtkwin_about = gtk_window_new (GTK_WINDOW_DIALOG); 02584 gtk_window_position (GTK_WINDOW (gtkwin_about), GTK_WIN_POS_CENTER); 02585 gtk_widget_set_usize (gtkwin_about,500,210); 02586 gtk_window_set_title (GTK_WINDOW (gtkwin_about), "About Crossfire"); 02587 02588 gtk_signal_connect (GTK_OBJECT (gtkwin_about), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), >kwin_about); 02589 02590 gtk_container_border_width (GTK_CONTAINER (gtkwin_about), 0); 02591 vbox = gtk_vbox_new(FALSE, 2); 02592 gtk_container_add (GTK_CONTAINER(gtkwin_about),vbox); 02593 style = gtk_widget_get_style(gtkwin_about); 02594 gtk_widget_realize(gtkwin_about); 02595 aboutgdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_about->window, 02596 &aboutgdkmask, 02597 &style->bg[GTK_STATE_NORMAL], 02598 (gchar **)crossfiretitle_xpm); 02599 aboutgtkpixmap= gtk_pixmap_new (aboutgdkpixmap, aboutgdkmask); 02600 gtk_box_pack_start (GTK_BOX (vbox),aboutgtkpixmap, FALSE, TRUE, 0); 02601 gtk_widget_show (aboutgtkpixmap); 02602 02603 hbox = gtk_hbox_new(FALSE, 2); 02604 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 02605 02606 aboutlabel = gtk_text_new (NULL, NULL); 02607 gtk_text_set_editable (GTK_TEXT (aboutlabel), FALSE); 02608 gtk_box_pack_start (GTK_BOX (hbox),aboutlabel, TRUE, TRUE, 0); 02609 gtk_widget_show (aboutlabel); 02610 02611 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (aboutlabel)->vadj); 02612 gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0); 02613 02614 gtk_widget_show (vscrollbar); 02615 02616 gtk_widget_show (hbox); 02617 02618 hbox = gtk_hbox_new(FALSE, 2); 02619 02620 aboutbutton = gtk_button_new_with_label ("Close"); 02621 gtk_signal_connect_object (GTK_OBJECT (aboutbutton), "clicked", 02622 GTK_SIGNAL_FUNC(gtk_widget_destroy), 02623 GTK_OBJECT (gtkwin_about)); 02624 gtk_box_pack_start (GTK_BOX (hbox), aboutbutton, TRUE, FALSE, 0); 02625 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 02626 gtk_widget_show (aboutbutton); 02627 gtk_widget_show (hbox); 02628 02629 gtk_widget_show (vbox); 02630 gtk_widget_show (gtkwin_about); 02631 gtk_text_insert (GTK_TEXT (aboutlabel), NULL, &aboutlabel->style->black, 02632 NULL, VERSION_INFO , -1); 02633 gtk_text_insert (GTK_TEXT (aboutlabel), NULL, &aboutlabel->style->black, 02634 NULL, text , -1); 02635 gtk_adjustment_set_value(GTK_TEXT(aboutlabel)->vadj, 0.0); 02636 } 02637 else { 02638 gdk_window_raise (gtkwin_about->window); 02639 } 02640 } 02641 02642 static void createBugTracker(void) { 02643 if (bugtrack ==NULL){ 02644 LogEntry* le; 02645 bugtrack = gtk_text_new (NULL, NULL); 02646 gtk_signal_connect (GTK_OBJECT (bugtrack), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &bugtrack); 02647 gtk_text_set_editable (GTK_TEXT (bugtrack), FALSE); 02648 gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, "MESSAGES TRACK:\n" , -1); 02649 for (le=LogFirst;le;le=le->next) 02650 gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, getLogText(le) , -1); 02651 02652 } 02653 } 02654 02655 static void bugdialog(GtkWidget *widget) { 02656 #include "help/bugreport.h" 02657 GtkWidget *vbox; 02658 GtkWidget *hbox; 02659 GtkWidget *buglabel; 02660 GtkWidget *vscrollbar; 02661 GtkWidget *bugbutton; 02662 GtkWidget *buggtkpixmap; 02663 GdkPixmap *buggdkpixmap; 02664 GdkBitmap *buggdkmask; 02665 02666 GtkStyle *style; 02667 #ifndef CFGTK2 02668 GdkFont* font; 02669 #endif 02670 02671 if(!gtkwin_bug) { 02672 02673 gtkwin_bug = gtk_window_new (GTK_WINDOW_DIALOG); 02674 gtk_window_position (GTK_WINDOW (gtkwin_bug), GTK_WIN_POS_CENTER); 02675 gtk_widget_set_usize (gtkwin_bug,500,450); 02676 gtk_window_set_title (GTK_WINDOW (gtkwin_bug), "Report a bug in Crossfire"); 02677 02678 gtk_signal_connect (GTK_OBJECT (gtkwin_bug), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), >kwin_bug); 02679 /*gtk_signal_connect (GTK_OBJECT (gtkwin_bug), "destroy", GTK_SIGNAL_FUNC(bugreportdestroy), >kwin_bug);*/ 02680 02681 gtk_container_border_width (GTK_CONTAINER (gtkwin_bug), 0); 02682 vbox = gtk_vbox_new(FALSE, 2); 02683 gtk_container_add (GTK_CONTAINER(gtkwin_bug),vbox); 02684 style = gtk_widget_get_style(gtkwin_bug); 02685 gtk_widget_realize(gtkwin_bug); 02686 buggdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_bug->window, 02687 &buggdkmask, 02688 &style->bg[GTK_STATE_NORMAL], 02689 (gchar **)crossfiretitle_xpm); 02690 buggtkpixmap= gtk_pixmap_new (buggdkpixmap, buggdkmask); 02691 gtk_box_pack_start (GTK_BOX (vbox),buggtkpixmap, FALSE, TRUE, 0); 02692 gtk_widget_show (buggtkpixmap); 02693 02694 hbox = gtk_hbox_new(FALSE, 2); 02695 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 02696 02697 buglabel = gtk_text_new (NULL, NULL); 02698 gtk_widget_set_style(buglabel,style); 02699 /*GtkStyle* gtk_widget_get_style (GtkWidget *widget);*/ 02700 gtk_text_set_editable (GTK_TEXT (buglabel), FALSE); 02701 gtk_box_pack_start (GTK_BOX (hbox),buglabel, TRUE, TRUE, 0); 02702 gtk_widget_show (buglabel); 02703 02704 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (buglabel)->vadj); 02705 gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0); 02706 02707 gtk_widget_show (vscrollbar); 02708 02709 gtk_widget_show (hbox); 02710 hbox = gtk_hbox_new(FALSE, 2); 02711 createBugTracker(); 02712 #ifndef CFGTK2 02713 /* Win32 uses GTK2, this apparently doesn't work... */ 02714 font = gdk_font_load ("-*-fixed-*-*-*-*-12-*-*-*-*-*-*-*"); 02715 if (font){ 02716 style = gtk_style_copy(gtk_widget_get_style (bugtrack)); 02717 gdk_font_unref(style->font); 02718 style->font=font; /*no ref since transfert*/ 02719 font=NULL; 02720 gtk_widget_set_style(bugtrack,style); 02721 } 02722 #endif 02723 gtk_box_pack_start (GTK_BOX (hbox),bugtrack, TRUE, TRUE, 0); 02724 gtk_widget_show (bugtrack); 02725 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (bugtrack)->vadj); 02726 gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0); 02727 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 02728 gtk_widget_show (vscrollbar); 02729 gtk_widget_show (hbox); 02730 hbox = gtk_hbox_new(FALSE, 2); 02731 bugbutton = gtk_button_new_with_label ("Close"); 02732 gtk_signal_connect_object (GTK_OBJECT (bugbutton), "clicked", 02733 GTK_SIGNAL_FUNC(gtk_widget_destroy), 02734 GTK_OBJECT (gtkwin_bug)); 02735 gtk_box_pack_start (GTK_BOX (hbox), bugbutton, TRUE, FALSE, 0); 02736 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 02737 gtk_widget_show (bugbutton); 02738 gtk_widget_show (hbox); 02739 02740 gtk_widget_show (vbox); 02741 gtk_widget_show (gtkwin_bug); 02742 gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black, 02743 NULL, VERSION_INFO , -1); 02744 gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black, 02745 NULL, text , -1); 02746 02747 gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black, 02748 NULL, "\n\nVersion Information\n" , -1); 02749 02750 02751 gtk_adjustment_set_value(GTK_TEXT(buglabel)->vadj, 0.0); 02752 } 02753 else { 02754 gdk_window_raise (gtkwin_bug->window); 02755 } 02756 } 02757 02758 void cclist_button_event(GtkWidget *gtklist, gint row, gint column, GdkEventButton *event) { 02759 gchar *buf; 02760 if (event->button==1) { 02761 gtk_clist_get_text (GTK_CLIST(cclist), row, 0, &buf); 02762 gtk_label_set (GTK_LABEL(cnumentrytext), buf); 02763 gtk_clist_get_text (GTK_CLIST(cclist), row, 1, &buf); 02764 gtk_entry_set_text (GTK_ENTRY(ckeyentrytext), buf); 02765 gtk_clist_get_text (GTK_CLIST(cclist), row, 3, &buf); 02766 gtk_entry_set_text (GTK_ENTRY(cmodentrytext), buf); 02767 gtk_clist_get_text (GTK_CLIST(cclist), row, 4, &buf); 02768 gtk_entry_set_text (GTK_ENTRY(ckentrytext), buf); 02769 } 02770 } 02771 02772 02773 void disconnect(GtkWidget *widget) { 02774 #ifdef WIN32 02775 closesocket(csocket.fd); 02776 #else 02777 close(csocket.fd); 02778 #endif 02779 csocket.fd = -1; 02780 if (csocket_fd) { 02781 gdk_input_remove(csocket_fd); 02782 csocket_fd=0; 02783 gtk_main_quit(); 02784 } 02785 cleanup_textmanagers(); 02786 } 02787 02788 /* Ok, simplistic help system. Just put the text file up in a scrollable window */ 02789 02790 static void shelpdialog(GtkWidget *widget) { 02791 #include "help/shelp.h" 02792 GtkWidget *vbox; 02793 GtkWidget *hbox; 02794 GtkWidget *shelptext; 02795 GtkWidget *helpbutton; 02796 GtkWidget *vscrollbar; 02797 /* GtkStyle *style;*/ 02798 02799 if(!gtkwin_shelp) { 02800 02801 gtkwin_shelp = gtk_window_new (GTK_WINDOW_DIALOG); 02802 gtk_window_position (GTK_WINDOW (gtkwin_shelp), GTK_WIN_POS_CENTER); 02803 gtk_widget_set_usize (gtkwin_shelp,400,300); 02804 gtk_window_set_title (GTK_WINDOW (gtkwin_shelp), "Crossfire Server Help"); 02805 gtk_window_set_policy (GTK_WINDOW (gtkwin_shelp), TRUE, TRUE, FALSE); 02806 02807 gtk_signal_connect (GTK_OBJECT (gtkwin_shelp), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), >kwin_shelp); 02808 02809 gtk_container_border_width (GTK_CONTAINER (gtkwin_shelp), 0); 02810 vbox = gtk_vbox_new(FALSE, 2); 02811 gtk_container_add (GTK_CONTAINER(gtkwin_shelp),vbox); 02812 hbox = gtk_hbox_new(FALSE, 2); 02813 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 02814 02815 shelptext = gtk_text_new (NULL, NULL); 02816 gtk_text_set_editable (GTK_TEXT (shelptext), FALSE); 02817 gtk_box_pack_start (GTK_BOX (hbox),shelptext, TRUE, TRUE, 0); 02818 gtk_widget_show (shelptext); 02819 02820 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (shelptext)->vadj); 02821 gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0); 02822 02823 gtk_widget_show (vscrollbar); 02824 gtk_widget_show (hbox); 02825 02826 hbox = gtk_hbox_new(FALSE, 2); 02827 02828 helpbutton = gtk_button_new_with_label ("Close"); 02829 gtk_signal_connect_object (GTK_OBJECT (helpbutton), "clicked", 02830 GTK_SIGNAL_FUNC(gtk_widget_destroy), 02831 GTK_OBJECT (gtkwin_shelp)); 02832 gtk_box_pack_start (GTK_BOX (hbox), helpbutton, TRUE, FALSE, 0); 02833 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 02834 gtk_widget_show (helpbutton); 02835 gtk_widget_show (hbox); 02836 02837 gtk_widget_show (vbox); 02838 gtk_widget_show (gtkwin_shelp); 02839 gtk_text_insert (GTK_TEXT (shelptext), NULL, &shelptext->style->black, NULL, text , -1); 02840 } 02841 else { 02842 gdk_window_raise (gtkwin_shelp->window); 02843 } 02844 } 02845 02846 /* Various routines for setting modes by menu choices. */ 02847 static void new_menu_pickup(GtkWidget *button, int val) 02848 { 02849 char modestr[128]; 02850 unsigned int old_pickup = pickup_mode; 02851 02852 /* widget is GtkCheckMenuItem */ 02853 if(GTK_CHECK_MENU_ITEM (button)->active) { 02854 pickup_mode=pickup_mode|val; 02855 if (val != PU_NEWMODE) 02856 pickup_mode = pickup_mode | PU_NEWMODE; 02857 } else pickup_mode=pickup_mode&~val; 02858 02859 02860 if (old_pickup == pickup_mode) 02861 return; 02862 02863 #if 0 02864 fprintf(stderr,"val=0x%8x\n",val); 02865 fprintf(stderr,"mode=0x%8x\n",pmode); 02866 #endif 02867 02868 sprintf(modestr,"bind pickup %u",pickup_mode); 02869 draw_info("To set this pickup mode to a key, use:",NDI_BLACK); 02870 draw_info(modestr,NDI_BLACK); 02871 sprintf(modestr,"pickup %u",pickup_mode); 02872 send_command(modestr, -1, 0); 02873 } 02874 02875 02876 static void menu_pickup0(void) { 02877 pickup_mode = 0; 02878 send_command("pickup 0", -1, 0); 02879 } 02880 02881 static void menu_pickup1(void) { 02882 pickup_mode = 1; 02883 send_command("pickup 1", -1, 0); 02884 } 02885 02886 static void menu_pickup2(void) { 02887 pickup_mode = 2; 02888 send_command("pickup 2", -1, 0); 02889 } 02890 02891 static void menu_pickup3(void) { 02892 pickup_mode = 3; 02893 send_command("pickup 3", -1, 0); 02894 } 02895 02896 static void menu_pickup4(void) { 02897 pickup_mode = 4; 02898 send_command("pickup 4", -1, 0); 02899 } 02900 02901 static void menu_pickup5(void) { 02902 pickup_mode = 5; 02903 send_command("pickup 5", -1, 0); 02904 02905 } 02906 02907 static void menu_pickup6(void) { 02908 pickup_mode = 6; 02909 send_command("pickup 6", -1, 0); 02910 } 02911 02912 static void menu_pickup7(void) { 02913 pickup_mode = 7; 02914 send_command("pickup 7", -1, 0); 02915 } 02916 02917 static void menu_pickup10(void) { 02918 pickup_mode = 10; 02919 send_command("pickup 10", -1, 0); 02920 } 02921 02922 02923 02924 static void menu_who(void) { 02925 extended_command("who"); 02926 } 02927 02928 static void menu_apply(void) { 02929 extended_command("apply"); 02930 } 02931 02932 static void menu_cast(void) { 02933 gtk_entry_set_text(GTK_ENTRY(entrytext),"cast "); 02934 gtk_widget_grab_focus (GTK_WIDGET(entrytext)); 02935 } 02936 02937 static void menu_search(void) { 02938 extended_command("search"); 02939 } 02940 02941 static void menu_disarm(void) { 02942 extended_command("disarm"); 02943 } 02944 02945 static void spellinventory_redraw(GtkWidget* list, GdkEventVisibility* event, gpointer view_x) { 02946 item* ob; 02947 char buffer[2][MAX_BUF]; 02948 char* columns[2]; 02949 gint row, selected = -1; 02950 02951 if (GTK_CLIST(list)->selection != NULL) 02952 selected = GPOINTER_TO_INT(GTK_CLIST(list)->selection->data); 02953 02954 gtk_clist_freeze(GTK_CLIST(list)); 02955 gtk_clist_clear(GTK_CLIST(list)); 02956 02957 columns[0] = buffer[0]; 02958 columns[1] = buffer[1]; 02959 02960 for (ob = cpl.ob->inv; ob != NULL; ob = ob->next) { 02961 if (!can_write_spell_on(ob)) 02962 continue; 02963 snprintf(buffer[0], sizeof(buffer[0]), " "); 02964 snprintf(buffer[1], sizeof(buffer[1]), ob->d_name); 02965 row = gtk_clist_append(GTK_CLIST(list), columns); 02966 gtk_clist_set_pixmap (GTK_CLIST (list), row, 0, 02967 (GdkPixmap*)pixmaps[ob->face]->icon_image, 02968 (GdkBitmap*)pixmaps[ob->face]->icon_mask); 02969 gtk_clist_set_row_data (GTK_CLIST(list), row, ob); 02970 } 02971 02972 gtk_clist_thaw(GTK_CLIST(list)); 02973 02974 if (selected != -1) { 02975 gtk_clist_select_row(GTK_CLIST(list), selected, 1); 02976 gtk_clist_moveto(GTK_CLIST(list), selected, 0, 0, 0); 02977 } 02978 } 02979 02980 static GtkWidget *gtkwin_spell = NULL; /* Spell window */ 02981 static GtkWidget *description = NULL; /* The text box containing spell description */ 02982 static GtkWidget *list = NULL; 02983 static GtkWidget *spelloptions = NULL; /* Text box with extra options to pass to the spell */ 02984 GtkWidget *spellinventory = NULL; /* List containing inventory for spell inscription. Not static because 02985 will be changed by inventory.c*/ 02986 02987 static void click_inscribe_spell(void) { 02988 int selection; 02989 item *scroll; 02990 Spell* spell; 02991 02992 if (GTK_CLIST(spellinventory)->selection != NULL && GTK_CLIST(list)->selection != NULL) { 02993 selection = GPOINTER_TO_INT(GTK_CLIST(spellinventory)->selection->data); 02994 scroll = (item*)gtk_clist_get_row_data(GTK_CLIST(spellinventory), selection); 02995 02996 selection = GPOINTER_TO_INT(GTK_CLIST(list)->selection->data); 02997 spell = (Spell*)gtk_clist_get_row_data(GTK_CLIST(list), selection); 02998 02999 inscribe_magical_scroll(scroll, spell); 03000 } 03001 } 03002 03003 static void select_spell_event(GtkWidget *gtklist, gint row, gint column, 03004 GdkEventButton *event) { 03005 03006 char command[MAX_BUF], message[MAX_BUF]; 03007 Spell *spell = gtk_clist_get_row_data (GTK_CLIST(gtklist), row); 03008 char *options = NULL; 03009 03010 if (!event) return; /* We have nothing to do */ 03011 /* Any click will select the spell, and show it's description */ 03012 gtk_text_freeze(GTK_TEXT(description)); 03013 gtk_text_set_point(GTK_TEXT(description), 0); 03014 gtk_text_forward_delete(GTK_TEXT(description), gtk_text_get_length(GTK_TEXT(description))); 03015 sprintf(message, "%s - level %d %s spell\n\n%s", spell->name, spell->level, 03016 spell->skill?spell->skill:"generic", spell->message); 03017 gtk_text_insert(GTK_TEXT(description), NULL, NULL, NULL, message, -1); 03018 gtk_text_thaw(GTK_TEXT(description)); 03019 if (event->button==2) { /* On middle click, also invoke the spell */ 03020 options = gtk_editable_get_chars(GTK_EDITABLE(spelloptions), 0, -1); 03021 sprintf(command, "invoke %d %s", spell->tag, options); 03022 send_command(command, -1, 1); 03023 g_free(options); 03024 } 03025 else if (event->button==3) { /* On right click, also cast the spell */ 03026 options = gtk_editable_get_chars(GTK_EDITABLE(spelloptions), 0, -1); 03027 sprintf(command, "cast %d %s", spell->tag, options); 03028 send_command(command, -1, 1); 03029 g_free(options); 03030 } 03031 } 03032 03033 static void update_spell_list(int force) { 03034 gint row; 03035 char buffer[3][MAX_BUF]; 03036 char *columns[3]; 03037 Spell *spell; 03038 PixmapInfo * pixmap; 03039 03040 /* Only update if we have to */ 03041 if (!force && !cpl.spells_updated) return; 03042 if (!gtkwin_spell || !GTK_IS_CLIST(list) || !GTK_WIDGET_VISIBLE(gtkwin_spell)) return; 03043 03044 gtk_clist_freeze(GTK_CLIST(list)); 03045 03046 /* We are about to recreate the entire spell list, so remove the existing one first */ 03047 gtk_clist_clear(GTK_CLIST(list)); 03048 03049 for (spell = cpl.spelldata; spell; spell=spell->next) { 03050 if (!spell) break; 03051 pixmap = pixmaps[spell->face]; 03052 buffer[2][0]='\0'; 03053 buffer[0][0]='\0'; 03054 strcpy(buffer[1], spell->name); 03055 columns[0] = buffer[0]; 03056 columns[1] = buffer[1]; 03057 columns[2] = buffer[2]; 03058 if (spell->sp) sprintf(buffer[2], "%d mana ", spell->sp); 03059 if (spell->grace) sprintf(buffer[2]+strlen(buffer[2]), "%d grace ", spell->grace); 03060 if (spell->dam) sprintf(buffer[2]+strlen(buffer[2]), "%d damage ", spell->dam); 03061 03062 /* The columns array doesn't yet contain the data we need, but we can't set the 03063 * row colour until we create the row, so we create the row with gtk_clist_append() 03064 * set the colour, then reset the text in the second column 03065 */ 03066 row = gtk_clist_append(GTK_CLIST(list), columns); 03067 gtk_clist_set_row_data(GTK_CLIST(list), row, spell); 03068 if (spell->path & cpl.stats.denied) { 03069 gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_RED]); 03070 strcat(buffer[2], "(DENIED) "); 03071 } 03072 else if (spell->path & cpl.stats.attuned) { 03073 gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_GREEN]); 03074 strcat(buffer[2], "(attuned) "); 03075 } 03076 else if (spell->path & cpl.stats.repelled) { 03077 gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_ORANGE]); 03078 strcat(buffer[2], "(repelled) "); 03079 } 03080 gtk_clist_set_text(GTK_CLIST(list), row, 2, columns[2]); 03081 gtk_clist_set_pixmap (GTK_CLIST (list), row, 0, 03082 (GdkPixmap*)pixmap->icon_image, (GdkBitmap*)pixmap->icon_mask); 03083 } 03084 gtk_clist_thaw(GTK_CLIST(list)); 03085 cpl.spells_updated =0; 03086 } 03087 03088 static void menu_spells(void) { 03089 GtkWidget * scroll_window; 03090 GtkStyle * liststyle; 03091 GtkWidget *cancelbutton; 03092 GtkWidget * vbox; 03093 GtkWidget * optionsbox; 03094 GtkWidget * spelloptionslabel; 03095 GtkWidget * notebook; 03096 GtkWidget * label; 03097 GtkWidget * frame; 03098 GtkWidget * inscribebutton; 03099 GtkWidget * inscribewindow; 03100 gchar *titles[] = {" ", "Name", "Cost"}; 03101 gchar *titles_inv[] = {" ", "Name"}; 03102 03103 if (gtkwin_spell && GTK_IS_CLIST(list)) { 03104 /* The window is already created, re-present it */ 03105 if (GTK_WIDGET_VISIBLE(gtkwin_spell)) { 03106 gdk_window_raise(gtkwin_spell->window); 03107 return; 03108 } 03109 03110 /* The window is hidden at the moment, so we don't need to recreate it. 03111 * We can merely reshow it, but the spell list won't have updated while 03112 * it was hidden so we have to force an update */ 03113 gtk_widget_show_all(gtkwin_spell); 03114 update_spell_list(1); 03115 return; 03116 } 03117 03118 /* We can't use an existing version, so we must create a new one. First we 03119 * will deal with the window itself */ 03120 gtkwin_spell = gtk_window_new (GTK_WINDOW_DIALOG); 03121 gtk_window_set_default_size(GTK_WINDOW(gtkwin_spell), 400+image_size, 400+image_size); 03122 gtk_window_set_title(GTK_WINDOW (gtkwin_spell), "Cast Spell"); 03123 03124 /* Now for its contents: first we'll deal with the options widget */ 03125 spelloptions = gtk_entry_new(); 03126 spelloptionslabel = gtk_label_new("Spell Options:"); 03127 optionsbox = gtk_hbox_new(FALSE, 2); 03128 gtk_box_pack_start(GTK_BOX(optionsbox), spelloptionslabel, FALSE, FALSE, 0); 03129 gtk_box_pack_start(GTK_BOX(optionsbox), spelloptions, TRUE, TRUE, 0); 03130 03131 /* rNw the list scroll window */ 03132 scroll_window = gtk_scrolled_window_new (0,0); 03133 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), 03134 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 03135 03136 /* And the spell list itself */ 03137 list = gtk_clist_new_with_titles(3, titles); 03138 gtk_clist_set_column_width(GTK_CLIST(list), 1, image_size); 03139 gtk_clist_set_column_width(GTK_CLIST(list), 1, 200); 03140 gtk_clist_set_column_width(GTK_CLIST(list), 2, 200); 03141 gtk_clist_set_selection_mode(GTK_CLIST(list) , GTK_SELECTION_BROWSE); 03142 gtk_clist_set_row_height (GTK_CLIST(list), image_size); 03143 liststyle = gtk_rc_get_style(list); 03144 if (liststyle) { 03145 liststyle->bg[GTK_STATE_SELECTED] = gdk_grey; 03146 liststyle->fg[GTK_STATE_SELECTED] = gdk_black; 03147 gtk_widget_set_style (list, liststyle); 03148 } 03149 /* Set the actions for the mouse buttons to trigger the callback function */ 03150 gtk_clist_set_button_actions(GTK_CLIST(list), 1, GTK_BUTTON_SELECTS); 03151 gtk_clist_set_button_actions(GTK_CLIST(list), 2, GTK_BUTTON_SELECTS); 03152 gtk_signal_connect(GTK_OBJECT(list), "select_row", 03153 GTK_SIGNAL_FUNC(select_spell_event), NULL); 03154 03155 /* With all that done, we can now add it to the scroll window */ 03156 gtk_container_add(GTK_CONTAINER(scroll_window), list); 03157 03158 /* Now we'll create the description box */ 03159 description = gtk_text_new(NULL, NULL); 03160 gtk_text_set_editable(GTK_TEXT (description), FALSE); 03161 03162 /* Finally add a close button to the window */ 03163 cancelbutton = gtk_button_new_with_label("Close"); 03164 gtk_signal_connect_object (GTK_OBJECT (cancelbutton), "clicked", 03165 GTK_SIGNAL_FUNC(gtk_widget_hide_all), GTK_OBJECT (gtkwin_spell)); 03166 03167 notebook = gtk_notebook_new (); 03168 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP ); 03169 03170 label = gtk_label_new ("Information"); 03171 gtk_widget_show (label); 03172 03173 frame = gtk_frame_new("Spell information"); 03174 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); 03175 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); 03176 vbox = gtk_vbox_new(FALSE, 0); 03177 gtk_box_pack_start(GTK_BOX(vbox), optionsbox, FALSE, FALSE, 0); 03178 gtk_box_pack_start(GTK_BOX(vbox), description, TRUE, TRUE, 0); 03179 gtk_container_add (GTK_CONTAINER(frame), vbox); 03180 03181 /* Start of inventory list for inscription */ 03182 if (command_inscribe) { 03183 label = gtk_label_new ("Inscribe"); 03184 gtk_widget_show (label); 03185 03186 frame = gtk_frame_new("Inscribe a spell"); 03187 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); 03188 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label); 03189 vbox = gtk_vbox_new(FALSE, 0); 03190 label = gtk_label_new ("Choose the item to write on:"); 03191 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 03192 03193 inscribewindow = gtk_scrolled_window_new (0,0); 03194 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(inscribewindow), 03195 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 03196 03197 spellinventory = gtk_clist_new_with_titles(2, titles_inv); 03198 gtk_clist_set_column_width(GTK_CLIST(spellinventory), 0, image_size); 03199 gtk_clist_set_selection_mode(GTK_CLIST(spellinventory) , GTK_SELECTION_BROWSE); 03200 gtk_clist_set_row_height (GTK_CLIST(spellinventory), image_size); 03201 liststyle = gtk_rc_get_style(spellinventory); 03202 if (liststyle) { 03203 liststyle->bg[GTK_STATE_SELECTED] = gdk_grey; 03204 liststyle->fg[GTK_STATE_SELECTED] = gdk_black; 03205 gtk_widget_set_style (spellinventory, liststyle); 03206 } 03207 gtk_signal_connect(GTK_OBJECT(spellinventory), 03208 "visibility-notify-event", 03209 (GtkSignalFunc)spellinventory_redraw, NULL); 03210 gtk_widget_add_events(spellinventory, GDK_VISIBILITY_NOTIFY_MASK); 03211 03212 gtk_container_add(GTK_CONTAINER(inscribewindow), spellinventory); 03213 gtk_box_pack_start(GTK_BOX(vbox), inscribewindow, TRUE, TRUE, 0); 03214 03215 inscribebutton = gtk_button_new_with_label("Inscribe"); 03216 gtk_signal_connect_object (GTK_OBJECT (inscribebutton), "clicked", 03217 GTK_SIGNAL_FUNC(click_inscribe_spell), NULL); 03218 gtk_box_pack_start(GTK_BOX(vbox), inscribebutton, FALSE, FALSE, 0); 03219 03220 gtk_container_add (GTK_CONTAINER(frame), vbox); 03221 } 03222 /* End of inscription logic */ 03223 03224 /* vbox holds all the widgets we just created, in order */ 03225 vbox = gtk_vbox_new(FALSE, 2); 03226 03227 /* Ok, time to pack it all up */ 03228 gtk_container_add(GTK_CONTAINER(gtkwin_spell), vbox); 03229 gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0); 03230 03231 gtk_box_pack_start (GTK_BOX(vbox),notebook, TRUE, TRUE, 0); 03232 03233 gtk_box_pack_start(GTK_BOX(vbox), cancelbutton, FALSE, FALSE, 0); 03234 03235 gtk_widget_show_all(gtkwin_spell); 03236 03237 /* Let's add the spells to the list now */ 03238 update_spell_list(1); 03239 } 03240 03241 void menu_clear(void) { 03242 guint size; 03243 03244 size = gtk_text_get_length(GTK_TEXT (gtkwin_info_text)); 03245 gtk_text_freeze (GTK_TEXT (gtkwin_info_text)); 03246 gtk_text_set_point(GTK_TEXT (gtkwin_info_text), 0); 03247 gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text), size ); 03248 gtk_text_thaw (GTK_TEXT (gtkwin_info_text)); 03249 03250 #ifdef WIN32 03251 if ( gtkwin_info_text2 ) 03252 { 03253 #endif 03254 size = gtk_text_get_length(GTK_TEXT (gtkwin_info_text2)); 03255 gtk_text_freeze (GTK_TEXT (gtkwin_info_text2)); 03256 gtk_text_set_point(GTK_TEXT (gtkwin_info_text2), 0); 03257 gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text2), size ); 03258 gtk_text_thaw (GTK_TEXT (gtkwin_info_text2)); 03259 #ifdef WIN32 03260 } 03261 #endif 03262 } 03263 03264 static void sexit(void) 03265 { 03266 extended_command("quit"); 03267 } 03268 03269 void client_exit(void) { 03270 LOG(LOG_INFO,"gtk::client_exit","Exiting with return value 0."); 03271 #ifdef WIN32 03272 script_killall(); 03273 #endif 03274 exit(0); 03275 } 03276 03277 /* To keep track of pickup menus, and be able to check/uncheck them. */ 03278 static GtkWidget* pickup_menus[43]; 03279 static int pickup_value[43]; 03280 static int pickup_count = 0; 03281 03282 /* get_menu_display 03283 * This sets up menus 03284 */ 03285 03286 static int get_menu_display (GtkWidget *box) { 03287 GtkWidget *filemenu; 03288 GtkWidget *actionmenu; 03289 GtkWidget *pickupmenu; 03290 GtkWidget *newpickupmenu; 03291 GtkWidget *ratiopickupmenu; 03292 GtkWidget *weaponpickupmenu; 03293 GtkWidget *armourpickupmenu; 03294 GtkWidget *bookspickupmenu; 03295 GtkWidget *clientmenu; 03296 GtkWidget *helpmenu; 03297 GtkWidget *menu_bar; 03298 GtkWidget *root_filemenu; 03299 GtkWidget *root_helpmenu; 03300 GtkWidget *root_actionmenu; 03301 /* GtkWidget *sub_pickupmenu;*/ 03302 GtkWidget *root_clientmenu; 03303 GtkWidget *menu_items; 03304 GtkWidget *pickup_menu_item; 03305 GtkWidget *newpickup_menu_item; 03306 GtkWidget *ratiopickup_menu_item; 03307 GtkWidget *weaponpickup_menu_item; 03308 GtkWidget *armourpickup_menu_item; 03309 GtkWidget *bookspickup_menu_item; 03310 GSList *pickupgroup; 03311 GSList *ratiopickupgroup; 03312 int i; 03313 char menustring[128]; 03314 03315 03316 /* Init the menu-widget, and remember -- never 03317 * gtk_show_widget() the menu widget!! 03318 * This is the menu that holds the menu items, the one that 03319 * will pop up when you click on the "Root Menu" in the app */ 03320 filemenu = gtk_menu_new(); 03321 03322 /* Next we make a little loop that makes three menu-entries for "test-menu". 03323 * Notice the call to gtk_menu_append. Here we are adding a list of 03324 * menu items to our menu. Normally, we'd also catch the "clicked" 03325 * signal on each of the menu items and setup a callback for it, 03326 * but it's omitted here to save space. */ 03327 03328 menu_items = gtk_tearoff_menu_item_new (); 03329 gtk_menu_append (GTK_MENU (filemenu), menu_items); 03330 gtk_widget_show (menu_items); 03331 03332 menu_items = gtk_menu_item_new_with_label("Save config"); 03333 gtk_menu_append(GTK_MENU (filemenu), menu_items); 03334 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03335 GTK_SIGNAL_FUNC(save_defaults), NULL); 03336 gtk_widget_show(menu_items); 03337 03338 menu_items = gtk_menu_item_new_with_label("Save window positions"); 03339 gtk_menu_append(GTK_MENU (filemenu), menu_items); 03340 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03341 GTK_SIGNAL_FUNC(save_winpos), NULL); 03342 gtk_widget_show(menu_items); 03343 03344 menu_items = gtk_menu_item_new (); 03345 gtk_menu_append(GTK_MENU (filemenu), menu_items); 03346 gtk_widget_show(menu_items); 03347 03348 03349 menu_items = gtk_menu_item_new_with_label("Quit character"); 03350 gtk_menu_append(GTK_MENU (filemenu), menu_items); 03351 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03352 GTK_SIGNAL_FUNC(sexit), NULL); 03353 gtk_widget_show(menu_items); 03354 03355 menu_items = gtk_menu_item_new_with_label("Quit client"); 03356 gtk_menu_append(GTK_MENU (filemenu), menu_items); 03357 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03358 GTK_SIGNAL_FUNC(client_exit), NULL); 03359 gtk_widget_show(menu_items); 03360 03361 /* This is the root menu, and will be the label 03362 * displayed on the menu bar. There won't be a signal handler attached, 03363 * as it only pops up the rest of the menu when pressed. */ 03364 root_filemenu = gtk_menu_item_new_with_label("File"); 03365 03366 gtk_widget_show(root_filemenu); 03367 03368 /* Now we specify that we want our newly created "menu" to be the menu 03369 * for the "root menu" */ 03370 gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_filemenu), filemenu); 03371 03372 /* Do the clientmenu */ 03373 03374 clientmenu = gtk_menu_new(); 03375 03376 /* menu_items = gtk_menu_item_new_with_label("Navigator"); 03377 gtk_menu_append(GTK_MENU (clientmenu), menu_items); 03378 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03379 GTK_SIGNAL_FUNC(navbut), NULL); 03380 gtk_widget_show(menu_items);*/ 03381 03382 menu_items = gtk_tearoff_menu_item_new (); 03383 gtk_menu_append (GTK_MENU (clientmenu), menu_items); 03384 gtk_widget_show (menu_items); 03385 03386 menu_items = gtk_menu_item_new_with_label("Clear info"); 03387 gtk_menu_append(GTK_MENU (clientmenu), menu_items); 03388 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03389 GTK_SIGNAL_FUNC(menu_clear), NULL); 03390 gtk_widget_show(menu_items); 03391 03392 03393 menu_items = gtk_menu_item_new_with_label("Spells"); 03394 gtk_menu_append(GTK_MENU (clientmenu), menu_items); 03395 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03396 GTK_SIGNAL_FUNC(menu_spells), NULL); 03397 gtk_widget_show(menu_items); 03398 03399 menu_items = gtk_menu_item_new_with_label("Configure"); 03400 gtk_menu_append(GTK_MENU (clientmenu), menu_items); 03401 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03402 GTK_SIGNAL_FUNC(configdialog), NULL); 03403 gtk_widget_show(menu_items); 03404 03405 03406 menu_items = gtk_menu_item_new_with_label("Disconnect"); 03407 gtk_menu_append(GTK_MENU (clientmenu), menu_items); 03408 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03409 GTK_SIGNAL_FUNC(disconnect), NULL); 03410 gtk_widget_show(menu_items); 03411 03412 03413 root_clientmenu = gtk_menu_item_new_with_label("Client"); 03414 03415 gtk_widget_show(root_clientmenu); 03416 gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_clientmenu), clientmenu); 03417 03418 /* Do the actionmenu */ 03419 03420 actionmenu = gtk_menu_new(); 03421 03422 menu_items = gtk_tearoff_menu_item_new (); 03423 gtk_menu_append (GTK_MENU (actionmenu), menu_items); 03424 gtk_widget_show (menu_items); 03425 03426 menu_items = gtk_menu_item_new_with_label("Who"); 03427 gtk_menu_append(GTK_MENU (actionmenu), menu_items); 03428 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03429 GTK_SIGNAL_FUNC(menu_who), NULL); 03430 gtk_widget_show(menu_items); 03431 03432 menu_items = gtk_menu_item_new_with_label("Cast..."); 03433 gtk_menu_append(GTK_MENU (actionmenu), menu_items); 03434 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03435 GTK_SIGNAL_FUNC(menu_cast), NULL); 03436 gtk_widget_show(menu_items); 03437 03438 menu_items = gtk_menu_item_new_with_label("Apply"); 03439 gtk_menu_append(GTK_MENU (actionmenu), menu_items); 03440 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03441 GTK_SIGNAL_FUNC(menu_apply), NULL); 03442 gtk_widget_show(menu_items); 03443 03444 pickup_menu_item = gtk_menu_item_new_with_label("Pickup"); 03445 gtk_menu_append(GTK_MENU (actionmenu), pickup_menu_item); 03446 /* gtk_signal_connect_object(GTK_OBJECT(pickup_menu_item), "activate", 03447 GTK_SIGNAL_FUNC(menu_apply), NULL);*/ 03448 gtk_widget_show(pickup_menu_item); 03449 03450 newpickup_menu_item = gtk_menu_item_new_with_label("NEWPickup"); 03451 gtk_menu_append(GTK_MENU (actionmenu), newpickup_menu_item); 03452 gtk_widget_show(newpickup_menu_item); 03453 03454 menu_items = gtk_menu_item_new_with_label("Search"); 03455 gtk_menu_append(GTK_MENU (actionmenu), menu_items); 03456 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03457 GTK_SIGNAL_FUNC(menu_search), NULL); 03458 gtk_widget_show(menu_items); 03459 03460 menu_items = gtk_menu_item_new_with_label("Disarm"); 03461 gtk_menu_append(GTK_MENU (actionmenu), menu_items); 03462 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03463 GTK_SIGNAL_FUNC(menu_disarm), NULL); 03464 gtk_widget_show(menu_items); 03465 03466 03467 root_actionmenu = gtk_menu_item_new_with_label("Action"); 03468 03469 gtk_widget_show(root_actionmenu); 03470 gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_actionmenu), actionmenu); 03471 03472 /* Do the submenu */ 03473 03474 pickupmenu = gtk_menu_new(); 03475 03476 /* This allows you to change your pickup status. Eight different modes for pick up exist: ``don't pick up'',``pick up 1 03477 item'', ``pick up 1 item and stop'', ``stop before picking up'', ``pick up all items'', pick up all items and stop'', 03478 ``pick up all magic items'', ``pick up all coins and gems''. Whenever you move over a pile of stuff your pickup*/ 03479 pickupgroup=NULL; 03480 03481 menu_items = gtk_tearoff_menu_item_new (); 03482 gtk_menu_append (GTK_MENU (pickupmenu), menu_items); 03483 gtk_widget_show (menu_items); 03484 03485 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Don't pick up"); 03486 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03487 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03488 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03489 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03490 GTK_SIGNAL_FUNC(menu_pickup0), NULL); 03491 gtk_widget_show(menu_items); 03492 03493 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up 1 item"); 03494 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03495 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03496 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03497 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03498 GTK_SIGNAL_FUNC(menu_pickup1), NULL); 03499 gtk_widget_show(menu_items); 03500 03501 03502 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up 1 item and stop"); 03503 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03504 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03505 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03506 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03507 GTK_SIGNAL_FUNC(menu_pickup2), NULL); 03508 gtk_widget_show(menu_items); 03509 03510 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Stop before picking up."); 03511 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03512 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03513 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03514 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03515 GTK_SIGNAL_FUNC(menu_pickup3), NULL); 03516 gtk_widget_show(menu_items); 03517 03518 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all items."); 03519 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03520 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03521 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03522 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03523 GTK_SIGNAL_FUNC(menu_pickup4), NULL); 03524 gtk_widget_show(menu_items); 03525 03526 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all items and stop."); 03527 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03528 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03529 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03530 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03531 GTK_SIGNAL_FUNC(menu_pickup5), NULL); 03532 gtk_widget_show(menu_items); 03533 03534 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all magic items."); 03535 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03536 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03537 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03538 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03539 GTK_SIGNAL_FUNC(menu_pickup6), NULL); 03540 gtk_widget_show(menu_items); 03541 03542 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all coins and gems."); 03543 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03544 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03545 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03546 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03547 GTK_SIGNAL_FUNC(menu_pickup7), NULL); 03548 gtk_widget_show(menu_items); 03549 03550 menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pickup silver and higher value/weight."); 03551 pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items)); 03552 gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE); 03553 gtk_menu_append(GTK_MENU (pickupmenu), menu_items); 03554 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03555 GTK_SIGNAL_FUNC(menu_pickup10), NULL); 03556 gtk_widget_show(menu_items); 03557 03558 03559 /* sub_pickupmenu = gtk_menu_item_new_with_label("Action"); 03560 03561 gtk_widget_show(sub_pickupmenu);*/ 03562 gtk_menu_item_set_submenu(GTK_MENU_ITEM (pickup_menu_item), pickupmenu); 03563 /* ENDPICKUP */ 03564 03565 /* --------------------------------------------------------------------- */ 03566 /* --------------------------------------------------------------------- */ 03567 /* --------------------------------------------------------------------- */ 03568 /* --------------------------------------------------------------------- */ 03569 /* --------------------------------------------------------------------- */ 03570 03571 /* Root of the NEWPickup menu */ 03572 newpickupmenu = gtk_menu_new(); 03573 gtk_menu_item_set_submenu(GTK_MENU_ITEM(newpickup_menu_item), newpickupmenu); 03574 03575 menu_items = gtk_tearoff_menu_item_new(); 03576 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03577 gtk_widget_show(menu_items); 03578 03579 menu_items = gtk_check_menu_item_new_with_label("Enable NEW autopickup"); 03580 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03581 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03582 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03583 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_NEWMODE)); 03584 gtk_widget_show(menu_items); 03585 pickup_menus[pickup_count] = menu_items; 03586 pickup_value[pickup_count++] = PU_NEWMODE; 03587 03588 menu_items = gtk_check_menu_item_new_with_label("Inhibit autopickup"); 03589 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03590 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03591 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03592 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_INHIBIT)); 03593 gtk_widget_show(menu_items); 03594 pickup_menus[pickup_count] = menu_items; 03595 pickup_value[pickup_count++] = PU_INHIBIT; 03596 03597 menu_items = gtk_check_menu_item_new_with_label("Stop before pickup"); 03598 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03599 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03600 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03601 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_STOP)); 03602 gtk_widget_show(menu_items); 03603 pickup_menus[pickup_count] = menu_items; 03604 pickup_value[pickup_count++] = PU_STOP; 03605 03606 menu_items = gtk_check_menu_item_new_with_label("Debug autopickup"); 03607 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03608 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03609 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03610 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_DEBUG)); 03611 gtk_widget_show(menu_items); 03612 pickup_menus[pickup_count] = menu_items; 03613 pickup_value[pickup_count++] = PU_DEBUG; 03614 03615 03616 /* The ratio pickup submenu */ 03617 ratiopickupmenu = gtk_menu_new(); 03618 ratiopickup_menu_item = gtk_menu_item_new_with_label("Weight/Value Ratio"); 03619 gtk_menu_append(GTK_MENU(newpickupmenu), ratiopickup_menu_item); 03620 gtk_widget_show(ratiopickup_menu_item); 03621 gtk_menu_item_set_submenu(GTK_MENU_ITEM(ratiopickup_menu_item), ratiopickupmenu); 03622 03623 ratiopickupgroup=NULL; 03624 03625 menu_items = gtk_tearoff_menu_item_new(); 03626 gtk_menu_append(GTK_MENU(ratiopickupmenu), menu_items); 03627 gtk_widget_show(menu_items); 03628 03629 for (i=0;i<16;i++) 03630 { 03631 if (i==0) sprintf(menustring,"Ratio pickup OFF"); 03632 else sprintf(menustring,"Ratio >= %d",i*5); 03633 menu_items = gtk_radio_menu_item_new_with_label(ratiopickupgroup, menustring); 03634 ratiopickupgroup = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menu_items)); 03635 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03636 gtk_menu_append(GTK_MENU(ratiopickupmenu), menu_items); 03637 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03638 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(i)); 03639 gtk_widget_show(menu_items); 03640 pickup_menus[pickup_count] = menu_items; 03641 pickup_value[pickup_count++] = i; 03642 } 03643 03644 03645 /* Weapon pickup menu */ 03646 weaponpickupmenu = gtk_menu_new(); 03647 weaponpickup_menu_item = gtk_menu_item_new_with_label("Weapons"); 03648 gtk_menu_append(GTK_MENU(newpickupmenu), weaponpickup_menu_item); 03649 gtk_widget_show(weaponpickup_menu_item); 03650 gtk_menu_item_set_submenu(GTK_MENU_ITEM(weaponpickup_menu_item), weaponpickupmenu); 03651 03652 menu_items = gtk_tearoff_menu_item_new(); 03653 gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items); 03654 gtk_widget_show(menu_items); 03655 03656 menu_items = gtk_check_menu_item_new_with_label("All weapons"); 03657 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03658 gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items); 03659 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03660 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ALLWEAPON)); 03661 gtk_widget_show(menu_items); 03662 pickup_menus[pickup_count] = menu_items; 03663 pickup_value[pickup_count++] = PU_ALLWEAPON; 03664 03665 menu_items = gtk_check_menu_item_new_with_label("Missile Weapons"); 03666 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03667 gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items); 03668 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03669 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MISSILEWEAPON)); 03670 gtk_widget_show(menu_items); 03671 pickup_menus[pickup_count] = menu_items; 03672 pickup_value[pickup_count++] = PU_MISSILEWEAPON; 03673 03674 menu_items = gtk_check_menu_item_new_with_label("Bows"); 03675 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03676 gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items); 03677 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03678 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_BOW)); 03679 gtk_widget_show(menu_items); 03680 pickup_menus[pickup_count] = menu_items; 03681 pickup_value[pickup_count++] = PU_BOW; 03682 03683 menu_items = gtk_check_menu_item_new_with_label("Arrows"); 03684 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03685 gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items); 03686 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03687 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ARROW)); 03688 gtk_widget_show(menu_items); 03689 pickup_menus[pickup_count] = menu_items; 03690 pickup_value[pickup_count++] = PU_ARROW; 03691 03692 03693 /* Armour pickup menu */ 03694 armourpickupmenu = gtk_menu_new(); 03695 armourpickup_menu_item = gtk_menu_item_new_with_label("Armour"); 03696 gtk_menu_append(GTK_MENU(newpickupmenu), armourpickup_menu_item); 03697 gtk_widget_show(armourpickup_menu_item); 03698 gtk_menu_item_set_submenu(GTK_MENU_ITEM(armourpickup_menu_item), armourpickupmenu); 03699 03700 menu_items = gtk_tearoff_menu_item_new(); 03701 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03702 gtk_widget_show(menu_items); 03703 03704 menu_items = gtk_check_menu_item_new_with_label("Helmets"); 03705 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03706 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03707 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03708 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_HELMET)); 03709 gtk_widget_show(menu_items); 03710 pickup_menus[pickup_count] = menu_items; 03711 pickup_value[pickup_count++] = PU_HELMET; 03712 03713 menu_items = gtk_check_menu_item_new_with_label("Shields"); 03714 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03715 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03716 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03717 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SHIELD)); 03718 gtk_widget_show(menu_items); 03719 pickup_menus[pickup_count] = menu_items; 03720 pickup_value[pickup_count++] = PU_SHIELD; 03721 03722 menu_items = gtk_check_menu_item_new_with_label("Body Armour"); 03723 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03724 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03725 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03726 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ARMOUR)); 03727 gtk_widget_show(menu_items); 03728 pickup_menus[pickup_count] = menu_items; 03729 pickup_value[pickup_count++] = PU_ARMOUR; 03730 03731 menu_items = gtk_check_menu_item_new_with_label("Boots"); 03732 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03733 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03734 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03735 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_BOOTS)); 03736 gtk_widget_show(menu_items); 03737 pickup_menus[pickup_count] = menu_items; 03738 pickup_value[pickup_count++] = PU_BOOTS; 03739 03740 menu_items = gtk_check_menu_item_new_with_label("Gloves"); 03741 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03742 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03743 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03744 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_GLOVES)); 03745 gtk_widget_show(menu_items); 03746 pickup_menus[pickup_count] = menu_items; 03747 pickup_value[pickup_count++] = PU_GLOVES; 03748 03749 menu_items = gtk_check_menu_item_new_with_label("Cloaks"); 03750 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03751 gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items); 03752 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03753 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_CLOAK)); 03754 gtk_widget_show(menu_items); 03755 pickup_menus[pickup_count] = menu_items; 03756 pickup_value[pickup_count++] = PU_CLOAK; 03757 03758 03759 /* Books pickup menu */ 03760 bookspickupmenu = gtk_menu_new(); 03761 bookspickup_menu_item = gtk_menu_item_new_with_label("Books"); 03762 gtk_menu_append(GTK_MENU(newpickupmenu), bookspickup_menu_item); 03763 gtk_widget_show(bookspickup_menu_item); 03764 gtk_menu_item_set_submenu(GTK_MENU_ITEM(bookspickup_menu_item), bookspickupmenu); 03765 03766 menu_items = gtk_tearoff_menu_item_new(); 03767 gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items); 03768 gtk_widget_show(menu_items); 03769 03770 menu_items = gtk_check_menu_item_new_with_label("Spellbooks"); 03771 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03772 gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items); 03773 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03774 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SPELLBOOK)); 03775 gtk_widget_show(menu_items); 03776 pickup_menus[pickup_count] = menu_items; 03777 pickup_value[pickup_count++] = PU_SPELLBOOK; 03778 03779 menu_items = gtk_check_menu_item_new_with_label("Skillscrolls"); 03780 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03781 gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items); 03782 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03783 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SKILLSCROLL)); 03784 gtk_widget_show(menu_items); 03785 pickup_menus[pickup_count] = menu_items; 03786 pickup_value[pickup_count++] = PU_SKILLSCROLL; 03787 03788 menu_items = gtk_check_menu_item_new_with_label("Normal Books/Scrolls"); 03789 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03790 gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items); 03791 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03792 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_READABLES)); 03793 gtk_widget_show(menu_items); 03794 pickup_menus[pickup_count] = menu_items; 03795 pickup_value[pickup_count++] = PU_READABLES; 03796 03797 03798 /* Continue with the rest of the stuff... */ 03799 03800 menu_items = gtk_check_menu_item_new_with_label("Food"); 03801 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03802 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03803 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03804 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_FOOD)); 03805 gtk_widget_show(menu_items); 03806 pickup_menus[pickup_count] = menu_items; 03807 pickup_value[pickup_count++] = PU_FOOD; 03808 03809 menu_items = gtk_check_menu_item_new_with_label("Drinks"); 03810 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03811 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03812 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03813 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_DRINK)); 03814 gtk_widget_show(menu_items); 03815 pickup_menus[pickup_count] = menu_items; 03816 pickup_value[pickup_count++] = PU_DRINK; 03817 03818 menu_items = gtk_check_menu_item_new_with_label("Flesh"); 03819 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03820 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03821 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03822 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_FLESH)); 03823 gtk_widget_show(menu_items); 03824 pickup_menus[pickup_count] = menu_items; 03825 pickup_value[pickup_count++] = PU_FLESH; 03826 03827 menu_items = gtk_check_menu_item_new_with_label("Valuables (Money, Gems)"); 03828 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03829 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03830 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03831 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_VALUABLES)); 03832 gtk_widget_show(menu_items); 03833 pickup_menus[pickup_count] = menu_items; 03834 pickup_value[pickup_count++] = PU_VALUABLES; 03835 03836 menu_items = gtk_check_menu_item_new_with_label("Keys"); 03837 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03838 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03839 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03840 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_KEY)); 03841 gtk_widget_show(menu_items); 03842 pickup_menus[pickup_count] = menu_items; 03843 pickup_value[pickup_count++] = PU_KEY; 03844 03845 menu_items = gtk_check_menu_item_new_with_label("Magical Items"); 03846 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03847 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03848 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03849 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MAGICAL)); 03850 gtk_widget_show(menu_items); 03851 pickup_menus[pickup_count] = menu_items; 03852 pickup_value[pickup_count++] = PU_MAGICAL; 03853 03854 menu_items = gtk_check_menu_item_new_with_label("Potions"); 03855 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03856 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03857 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03858 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_POTION)); 03859 gtk_widget_show(menu_items); 03860 pickup_menus[pickup_count] = menu_items; 03861 pickup_value[pickup_count++] = PU_POTION; 03862 03863 menu_items = gtk_check_menu_item_new_with_label("Magic Devices"); 03864 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03865 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03866 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03867 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MAGIC_DEVICE)); 03868 gtk_widget_show(menu_items); 03869 pickup_menus[pickup_count] = menu_items; 03870 pickup_value[pickup_count++] = PU_MAGIC_DEVICE; 03871 03872 menu_items = gtk_check_menu_item_new_with_label("Ignore cursed"); 03873 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03874 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03875 gtk_signal_connect(GTK_OBJECT(menu_items), "activate", 03876 GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_NOT_CURSED)); 03877 gtk_widget_show(menu_items); 03878 pickup_menus[pickup_count] = menu_items; 03879 pickup_value[pickup_count++] = PU_NOT_CURSED; 03880 03881 menu_items = gtk_check_menu_item_new_with_label("Jewelry"); 03882 gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE); 03883 gtk_menu_append(GTK_MENU(newpickupmenu), menu_items); 03884 gtk_signal_connect(GTK_OBJECT(menu_items),"activate", 03885 GTK_SIGNAL_FUNC(new_menu_pickup),GINT_TO_POINTER(PU_JEWELS)); 03886 gtk_widget_show(menu_items); 03887 pickup_menus[pickup_count] = menu_items; 03888 pickup_value[pickup_count++] = PU_JEWELS; 03889 /* --------------------------------------------------------------------- */ 03890 /* --------------------------------------------------------------------- */ 03891 /* --------------------------------------------------------------------- */ 03892 /* --------------------------------------------------------------------- */ 03893 /* --------------------------------------------------------------------- */ 03894 03895 /*Do the helpmenu */ 03896 helpmenu = gtk_menu_new(); 03897 03898 menu_items = gtk_tearoff_menu_item_new (); 03899 gtk_menu_append (GTK_MENU (helpmenu), menu_items); 03900 gtk_widget_show (menu_items); 03901 03902 menu_items = gtk_menu_item_new_with_label("Client commands"); 03903 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03904 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03905 GTK_SIGNAL_FUNC(chelpdialog), NULL); 03906 gtk_widget_show(menu_items); 03907 03908 menu_items = gtk_menu_item_new_with_label("Server help"); 03909 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03910 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03911 GTK_SIGNAL_FUNC(shelpdialog), NULL); 03912 gtk_widget_show(menu_items); 03913 03914 menu_items = gtk_menu_item_new (); 03915 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03916 gtk_widget_show(menu_items); 03917 03918 /* Link to things like the client-walkthrough and the playbook? */ 03919 03920 menu_items = gtk_menu_item_new_with_label("Report a bug"); 03921 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03922 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03923 GTK_SIGNAL_FUNC(bugdialog), NULL); 03924 gtk_widget_show(menu_items); 03925 03926 menu_items = gtk_menu_item_new (); 03927 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03928 gtk_widget_show(menu_items); 03929 03930 03931 menu_items = gtk_menu_item_new_with_label("About"); 03932 gtk_menu_append(GTK_MENU (helpmenu), menu_items); 03933 gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate", 03934 GTK_SIGNAL_FUNC(aboutdialog), NULL); 03935 gtk_widget_show(menu_items); 03936 03937 root_helpmenu = gtk_menu_item_new_with_label("Help"); 03938 03939 gtk_widget_show(root_helpmenu); 03940 gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_helpmenu), helpmenu); 03941 03942 /* Create a menu-bar to hold the menus and add it to our main window */ 03943 03944 03945 menu_bar = gtk_menu_bar_new(); 03946 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 2); 03947 gtk_widget_show(menu_bar); 03948 03949 /* Create a button to which to attach menu as a popup */ 03950 03951 /* And finally we append the menu-item to the menu-bar -- this is the 03952 * "root" menu-item I have been raving about =) */ 03953 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_filemenu); 03954 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_clientmenu); 03955 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_actionmenu); 03956 gtk_menu_item_right_justify (GTK_MENU_ITEM(root_helpmenu)); 03957 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_helpmenu); 03958 03959 /* Always display the window as the last step so it all splashes on 03960 * the screen at once. */ 03961 03962 return 0; 03963 } 03964 03965 03966 03967 /* get_root_display: 03968 * This sets up the root window (or none, if in split 03969 * windows mode, and also scans for any Xdefaults. Right now, only 03970 * splitwindow and image are used. image is the display 03971 * mechanism to use. I thought having one type that is set 03972 * to font, xpm, or pixmap was better than using xpm and pixmap 03973 * resources with on/off values (which gets pretty weird 03974 * if one of this is set to off. 03975 */ 03976 03977 03978 /* Create the splash window at startup */ 03979 03980 static void create_splash(void) { 03981 GtkWidget *vbox; 03982 GtkWidget *aboutgtkpixmap; 03983 GdkPixmap *aboutgdkpixmap; 03984 GdkBitmap *aboutgdkmask; 03985 GtkStyle *style; 03986 03987 gtkwin_splash = gtk_window_new (GTK_WINDOW_DIALOG); 03988 gtk_window_position (GTK_WINDOW (gtkwin_splash), GTK_WIN_POS_CENTER); 03989 gtk_widget_set_usize (gtkwin_splash,346,87); 03990 gtk_window_set_title (GTK_WINDOW (gtkwin_splash), "Welcome to Crossfire"); 03991 gtk_signal_connect (GTK_OBJECT (gtkwin_splash), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), >kwin_splash); 03992 03993 gtk_container_border_width (GTK_CONTAINER (gtkwin_splash), 0); 03994 vbox = gtk_vbox_new(FALSE, 0); 03995 gtk_container_add (GTK_CONTAINER(gtkwin_splash),vbox); 03996 style = gtk_widget_get_style(gtkwin_splash); 03997 gtk_widget_realize(gtkwin_splash); 03998 aboutgdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_splash->window, 03999 &aboutgdkmask, 04000 &style->bg[GTK_STATE_NORMAL], 04001 (gchar **)crossfiretitle_xpm); 04002 aboutgtkpixmap= gtk_pixmap_new (aboutgdkpixmap, aboutgdkmask); 04003 gtk_box_pack_start (GTK_BOX (vbox),aboutgtkpixmap, FALSE, TRUE, 0); 04004 gtk_widget_show (aboutgtkpixmap); 04005 04006 gtk_widget_show (vbox); 04007 gtk_widget_show (gtkwin_splash); 04008 04009 04010 while ( gtk_events_pending() ) { 04011 gtk_main_iteration(); 04012 } 04013 sleep (1); 04014 while ( gtk_events_pending() ) { 04015 gtk_main_iteration(); 04016 } 04017 04018 } 04019 04020 04021 static void destroy_splash(void) { 04022 gtk_widget_destroy(gtkwin_splash); 04023 } 04024 04025 /* Error handlers removed. Right now, there is nothing for 04026 * the client to do if it gets a fatal error - it doesn't have 04027 * any information to save. And we might as well let the standard 04028 * X11 error handler handle non fatal errors. 04029 */ 04030 04031 04032 void create_windows(void) { 04033 GtkWidget *rootvbox; 04034 GtkWidget *frame; 04035 int i; 04036 04037 tooltips = gtk_tooltips_new(); 04038 04039 if (want_config[CONFIG_SPLITWIN]==FALSE) { 04040 GtkStyle *style; 04041 int gcw; 04042 int gch; 04043 int rootwin_width; 04044 int rootwin_height; 04045 04046 gtkwin_root = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04047 style = gtk_rc_get_style(gtkwin_root); 04048 if (style) { 04049 #ifdef CFGTK2 /* GTK 2.2 stuff */ 04050 gcw = gdk_char_width(gdk_font_from_description(style->font_desc), '0') + 4; 04051 gch = gdk_char_height(gdk_font_from_description(style->font_desc), '0') + 2; 04052 #else 04053 gcw = gdk_char_width(style->font, '0') + 4; 04054 gch = gdk_char_height(style->font, '0') + 2; 04055 #endif 04056 } else { 04057 /* These are what the old defaults values were */ 04058 gcw = 11; 04059 gch = 10; 04060 } 04061 04062 gtk_widget_set_events (gtkwin_root, GDK_KEY_RELEASE_MASK); 04063 gtk_widget_set_uposition (gtkwin_root, 0, 0); 04064 04065 if ((55*gcw)+(map_image_size*use_config[CONFIG_MAPWIDTH]) >= gdk_screen_width()) 04066 rootwin_width = gdk_screen_width() - 30; 04067 else 04068 rootwin_width = (55*gcw)+(map_image_size*use_config[CONFIG_MAPWIDTH]); 04069 if ((33*gch)+(map_image_size*use_config[CONFIG_MAPHEIGHT]) >= gdk_screen_height()) 04070 rootwin_height = gdk_screen_height() - 50; 04071 else 04072 rootwin_height = (33*gch)+(map_image_size*use_config[CONFIG_MAPHEIGHT]); 04073 gtk_widget_set_usize (gtkwin_root,rootwin_width,rootwin_height); 04074 gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire GTK Client"); 04075 gtk_signal_connect_object(GTK_OBJECT(gtkwin_root), "destroy",GTK_SIGNAL_FUNC(main_window_destroyed), NULL); 04076 04077 gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0); 04078 04079 /* Alloc colors. colorname[] comes from xutil.c */ 04080 for (i=0; i<=12; i++ ) { 04081 if ( !gdk_color_parse(colorname[i], &root_color[i])) { 04082 printf ("cparse failed (%s)\n",colorname[i]); 04083 } 04084 if ( !gdk_color_alloc (gtk_widget_get_colormap (gtkwin_root), &root_color[i])) { 04085 printf ("calloc failed\n"); 04086 } 04087 } 04088 04089 /* menu / windows division */ 04090 rootvbox = gtk_vbox_new(FALSE, 0); 04091 gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox); 04092 gtk_widget_show (rootvbox); 04093 04094 get_menu_display(rootvbox); 04095 04096 /* first horizontal division. inv+obj on left, rest on right */ 04097 04098 inv_hpane = gtk_hpaned_new (); 04099 04100 gtk_box_pack_start (GTK_BOX (rootvbox), inv_hpane, TRUE, TRUE, 0); 04101 gtk_container_border_width (GTK_CONTAINER(inv_hpane), 5); 04102 gtk_widget_show (inv_hpane); 04103 04104 /* Divisior game+stats | text */ 04105 04106 stat_info_hpane = gtk_hpaned_new (); 04107 gtk_paned_add2 (GTK_PANED (inv_hpane), stat_info_hpane); 04108 04109 /* text frame */ 04110 04111 frame = gtk_frame_new (NULL); 04112 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); 04113 gtk_widget_set_usize (frame, (25*gcw), (30*gch)); 04114 gtk_paned_add2 (GTK_PANED (stat_info_hpane), frame); 04115 04116 get_info_display (frame); 04117 gtk_widget_show (frame); 04118 04119 /* game & statbars below, stats above */ 04120 stat_game_vpane = gtk_vpaned_new (); 04121 gtk_paned_add1 (GTK_PANED (stat_info_hpane), stat_game_vpane); 04122 04123 #if 0 04124 /* game - statbars */ 04125 if (want_config[CONFIG_MAPWIDTH]>15) { 04126 bigmap=TRUE; 04127 04128 game_bar_vpane = gtk_hpaned_new (); 04129 gtk_paned_add1 (GTK_PANED (stat_game_vpane), game_bar_vpane); 04130 } else { 04131 game_bar_vpane = gtk_vpaned_new (); 04132 gtk_paned_add2 (GTK_PANED (stat_game_vpane), game_bar_vpane); 04133 } 04134 #else 04135 game_bar_vpane = gtk_vpaned_new (); 04136 gtk_paned_add2 (GTK_PANED (stat_game_vpane), game_bar_vpane); 04137 #endif 04138 04139 04140 /* Statbars frame */ 04141 message_frame = gtk_frame_new (NULL); 04142 gtk_frame_set_shadow_type (GTK_FRAME(message_frame), GTK_SHADOW_ETCHED_IN); 04143 gtk_widget_set_usize (message_frame, (22*gcw)+6, (map_image_size*use_config[CONFIG_MAPHEIGHT])+6); 04144 gtk_paned_add2 (GTK_PANED (game_bar_vpane), message_frame); 04145 04146 get_message_display(message_frame); 04147 04148 gtk_widget_show (message_frame); 04149 04150 /* Game frame */ 04151 gameframe = gtk_frame_new (NULL); 04152 gtk_frame_set_shadow_type (GTK_FRAME(gameframe), GTK_SHADOW_ETCHED_IN); 04153 gtk_widget_set_usize (gameframe, (map_image_size*use_config[CONFIG_MAPWIDTH])+6, (map_image_size*use_config[CONFIG_MAPHEIGHT])+6); 04154 04155 if (bigmap) 04156 gtk_paned_add2 (GTK_PANED (stat_game_vpane), gameframe); 04157 else 04158 gtk_paned_add1 (GTK_PANED (game_bar_vpane), gameframe); 04159 04160 get_game_display (gameframe); 04161 04162 gtk_widget_show (gameframe); 04163 04164 /* stats frame */ 04165 stat_frame = gtk_frame_new (NULL); 04166 gtk_frame_set_shadow_type (GTK_FRAME(stat_frame), GTK_SHADOW_ETCHED_IN); 04167 if (bigmap) 04168 gtk_paned_add1 (GTK_PANED (game_bar_vpane), stat_frame); 04169 else 04170 gtk_paned_add1 (GTK_PANED (stat_game_vpane), stat_frame); 04171 04172 get_stats_display (stat_frame); 04173 04174 gtk_widget_show (stat_frame); 04175 04176 gtk_widget_show (game_bar_vpane); 04177 gtk_widget_show (stat_game_vpane); 04178 04179 inv_look_vpane = gtk_vpaned_new (); 04180 gtk_paned_add1 (GTK_PANED (inv_hpane), inv_look_vpane); 04181 04182 /* inventory frame */ 04183 frame = gtk_frame_new (NULL); 04184 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); 04185 gtk_widget_set_usize (frame, (24*gcw), (33*gch)); 04186 gtk_paned_add1 (GTK_PANED (inv_look_vpane), frame); 04187 04188 get_inv_display (frame); 04189 04190 gtk_widget_show (frame); 04191 04192 /* look frame */ 04193 frame = gtk_frame_new (NULL); 04194 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); 04195 gtk_widget_set_usize (frame, (24*gcw), (12*gch)); 04196 gtk_paned_add2 (GTK_PANED (inv_look_vpane), frame); 04197 04198 get_look_display (frame); 04199 04200 gtk_widget_show (frame); 04201 04202 gtk_widget_show (inv_look_vpane); 04203 04204 gtk_widget_show (stat_info_hpane); 04205 04206 gtk_widget_show (inv_hpane); 04207 04208 04209 /* Connect signals */ 04210 04211 gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event", 04212 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root)); 04213 gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event", 04214 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root)); 04215 gtk_widget_show (gtkwin_root); 04216 04217 #ifdef HAVE_SDL 04218 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) 04219 init_SDL( drawingarea, 0); 04220 #endif 04221 04222 } else { /* split window mode */ 04223 04224 04225 /* game window */ 04226 04227 gtkwin_root = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04228 gtk_widget_set_events (gtkwin_root, GDK_KEY_RELEASE_MASK); 04229 gtk_widget_set_uposition (gtkwin_root, 300, 160); 04230 gtk_widget_set_usize (gtkwin_root,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,(map_image_size*use_config[CONFIG_MAPHEIGHT])+6); 04231 gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire - view"); 04232 gtk_window_set_policy (GTK_WINDOW (gtkwin_root), TRUE, TRUE, FALSE); 04233 gtk_signal_connect_object(GTK_OBJECT(gtkwin_root), "destroy",GTK_SIGNAL_FUNC(main_window_destroyed), NULL); 04234 04235 04236 gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0); 04237 04238 04239 rootvbox = gtk_vbox_new(FALSE, 0); 04240 gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox); 04241 04242 gtk_widget_realize (rootvbox); 04243 04244 gtk_widget_realize (gtkwin_root); 04245 04246 04247 04248 gtk_widget_show (rootvbox); 04249 gtk_widget_show (gtkwin_root); 04250 gtk_widget_draw (gtkwin_root,NULL); 04251 gtk_widget_draw (rootvbox,NULL); 04252 04253 get_game_display(rootvbox); 04254 04255 04256 04257 /* Stats and menu window */ 04258 gtkwin_stats = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04259 gtk_widget_set_events (gtkwin_stats, GDK_KEY_RELEASE_MASK); 04260 gtk_widget_set_uposition (gtkwin_stats, 300, 0); 04261 gtk_widget_set_usize (gtkwin_stats,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,140); 04262 gtk_window_set_title (GTK_WINDOW (gtkwin_stats), "Crossfire GTK Client"); 04263 gtk_window_set_policy (GTK_WINDOW (gtkwin_stats), TRUE, TRUE, FALSE); 04264 gtk_signal_connect (GTK_OBJECT (gtkwin_stats), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), >kwin_stats); 04265 04266 gtk_container_border_width (GTK_CONTAINER (gtkwin_stats), 0); 04267 04268 04269 rootvbox = gtk_vbox_new(FALSE, 0); 04270 gtk_container_add (GTK_CONTAINER (gtkwin_stats), rootvbox); 04271 gtk_widget_show (rootvbox); 04272 04273 get_menu_display(rootvbox); 04274 get_stats_display (rootvbox); 04275 gtk_widget_realize (gtkwin_stats); 04276 gdk_window_set_group (gtkwin_stats->window, gtkwin_root->window); 04277 gtk_widget_show (gtkwin_stats); 04278 04279 04280 /* info window - text and messages */ 04281 gtkwin_info = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04282 gtk_widget_set_events (gtkwin_info, GDK_KEY_RELEASE_MASK); 04283 gtk_widget_set_uposition (gtkwin_info, 570, 0); 04284 gtk_widget_set_usize (gtkwin_info,400,600); 04285 gtk_window_set_title (GTK_WINDOW (gtkwin_info), "Crossfire - info"); 04286 gtk_window_set_policy (GTK_WINDOW (gtkwin_info), TRUE, TRUE, FALSE); 04287 gtk_signal_connect (GTK_OBJECT (gtkwin_info), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), >kwin_info); 04288 04289 gtk_container_border_width (GTK_CONTAINER (gtkwin_info), 0); 04290 04291 /* Alloc colors - not entirely necessary, really, since GTK should do this */ 04292 /* colorname[] comes from xutil.c */ 04293 for (i=0; i<=12; i++ ) { 04294 if ( !gdk_color_parse(colorname[i], &root_color[i])) { 04295 printf ("cparse failed (%s)\n",colorname[i]); 04296 } 04297 if ( !gdk_color_alloc (gtk_widget_get_colormap (gtkwin_info), &root_color[i])) { 04298 printf ("calloc failed\n"); 04299 } 04300 } 04301 04302 rootvbox = gtk_vbox_new(FALSE, 0); 04303 gtk_container_add (GTK_CONTAINER (gtkwin_info), rootvbox); 04304 gtk_widget_show (rootvbox); 04305 04306 get_info_display(rootvbox); 04307 04308 gtk_widget_show (gtkwin_info); 04309 gtk_widget_realize (gtkwin_info); 04310 gdk_window_set_group (gtkwin_info->window, gtkwin_root->window); 04311 04312 /* statbars window */ 04313 gtkwin_message = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04314 gtk_widget_set_events (gtkwin_message, GDK_KEY_RELEASE_MASK); 04315 gtk_widget_set_uposition (gtkwin_message, 300, 450); 04316 gtk_widget_set_usize (gtkwin_message,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,170); 04317 gtk_window_set_title (GTK_WINDOW (gtkwin_message), "Crossfire - vitals"); 04318 gtk_window_set_policy (GTK_WINDOW (gtkwin_message), TRUE, TRUE, FALSE); 04319 gtk_signal_connect (GTK_OBJECT (gtkwin_message), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), >kwin_message); 04320 04321 gtk_container_border_width (GTK_CONTAINER (gtkwin_message), 0); 04322 04323 04324 rootvbox = gtk_vbox_new(FALSE, 0); 04325 gtk_container_add (GTK_CONTAINER (gtkwin_message), rootvbox); 04326 gtk_widget_show (rootvbox); 04327 04328 get_message_display(rootvbox); 04329 04330 gtk_widget_show (gtkwin_message); 04331 gtk_widget_realize (gtkwin_message); 04332 gdk_window_set_group (gtkwin_message->window, gtkwin_root->window); 04333 04334 /* inventory window */ 04335 gtkwin_inv = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04336 gtk_widget_set_events (gtkwin_inv, GDK_KEY_RELEASE_MASK); 04337 gtk_widget_set_uposition (gtkwin_inv, 0, 0); 04338 gtk_widget_set_usize (gtkwin_inv,290,400); 04339 gtk_window_set_title (GTK_WINDOW (gtkwin_inv), "Crossfire - inventory"); 04340 gtk_window_set_policy (GTK_WINDOW (gtkwin_inv), TRUE, TRUE, FALSE); 04341 gtk_signal_connect (GTK_OBJECT (gtkwin_inv), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), >kwin_inv); 04342 04343 gtk_container_border_width (GTK_CONTAINER (gtkwin_inv), 0); 04344 04345 04346 rootvbox = gtk_vbox_new(FALSE, 0); 04347 gtk_container_add (GTK_CONTAINER (gtkwin_inv), rootvbox); 04348 gtk_widget_show (rootvbox); 04349 04350 get_inv_display(rootvbox); 04351 04352 gtk_widget_show (gtkwin_inv); 04353 gtk_widget_realize (gtkwin_inv); 04354 gdk_window_set_group (gtkwin_inv->window, gtkwin_root->window); 04355 /* look window */ 04356 gtkwin_look = gtk_window_new (GTK_WINDOW_TOPLEVEL); 04357 gtk_widget_set_events (gtkwin_look, GDK_KEY_RELEASE_MASK); 04358 gtk_widget_set_uposition (gtkwin_look, 0, 420); 04359 gtk_widget_set_usize (gtkwin_look,290,150); 04360 gtk_window_set_title (GTK_WINDOW (gtkwin_look), "Crossfire - look"); 04361 gtk_window_set_policy (GTK_WINDOW (gtkwin_look), TRUE, TRUE, FALSE); 04362 gtk_signal_connect (GTK_OBJECT (gtkwin_look), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), >kwin_look); 04363 04364 gtk_container_border_width (GTK_CONTAINER (gtkwin_look), 0); 04365 04366 04367 rootvbox = gtk_vbox_new(FALSE, 0); 04368 gtk_container_add (GTK_CONTAINER (gtkwin_look), rootvbox); 04369 gtk_widget_show (rootvbox); 04370 04371 get_look_display(rootvbox); 04372 04373 gtk_widget_show (gtkwin_look); 04374 gtk_widget_realize (gtkwin_look); 04375 gdk_window_set_group (gtkwin_look->window, gtkwin_root->window); 04376 /* Setup key events */ 04377 04378 gtk_signal_connect_object (GTK_OBJECT (gtkwin_message), "key_press_event", 04379 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_message)); 04380 gtk_signal_connect_object (GTK_OBJECT (gtkwin_message), "key_release_event", 04381 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_message)); 04382 04383 gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event", 04384 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root)); 04385 gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event", 04386 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root)); 04387 04388 gtk_signal_connect_object (GTK_OBJECT (gtkwin_info), "key_press_event", 04389 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_info)); 04390 gtk_signal_connect_object (GTK_OBJECT (gtkwin_info), "key_release_event", 04391 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_info)); 04392 04393 gtk_signal_connect_object (GTK_OBJECT (gtkwin_look), "key_press_event", 04394 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_look)); 04395 gtk_signal_connect_object (GTK_OBJECT (gtkwin_look), "key_release_event", 04396 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_look)); 04397 04398 gtk_signal_connect_object (GTK_OBJECT (gtkwin_inv), "key_press_event", 04399 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_inv)); 04400 gtk_signal_connect_object (GTK_OBJECT (gtkwin_inv), "key_release_event", 04401 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_inv)); 04402 04403 gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_press_event", 04404 GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_stats)); 04405 gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_release_event", 04406 GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_stats)); 04407 04408 #ifdef HAVE_SDL 04409 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) 04410 init_SDL( drawingarea, 0); 04411 #endif 04412 04413 } /* else split windows */ 04414 04415 /* load window positions from file */ 04416 set_window_pos(); 04417 gtk_tooltips_set_delay(tooltips, 1000 ); 04418 if (use_config[CONFIG_TOOLTIPS]) { 04419 gtk_tooltips_enable(tooltips); 04420 } 04421 04422 } 04423 04424 static int get_root_display(char *display_name,int gargc, char **gargv) { 04425 gtk_init (&gargc,&gargv); 04426 last_str=malloc(32767); 04427 04428 if (want_config[CONFIG_SPLASH]) create_splash(); 04429 /* we need to call gdk_rgb_init very early on, as some of the 04430 * create window functions may do callbacks in which case we try 04431 * to draw the game window. 04432 */ 04433 gdk_rgb_init(); 04434 create_windows(); 04435 04436 return 0; 04437 } 04438 04439 04440 /* null procedures. gtk does this for us. */ 04441 04442 /* TODO Make these commands specific to x11 toolkit. */ 04443 void set_scroll(const char *s) 04444 { 04445 } 04446 04447 04448 void set_autorepeat(const char *s) /* ...and what does this one *do*, anyway? */ 04449 { 04450 } 04451 04452 04453 int get_info_width(void) 04454 { 04455 /* 04456 * TODO Have crossfire-server send paragraphs rather than lines, so to 04457 * speak. Except for ASCII maps and things. Then this can go away 04458 * completely. 04459 */ 04460 return 40; 04461 } 04462 04463 04464 04465 /*********************************************************************** 04466 * 04467 * Here is the start of event handling functions 04468 * 04469 ***********************************************************************/ 04470 04471 04472 04473 /* This function handles the reading of the X Events and then 04474 * doing the appropriate action. For most input events, it is calling 04475 * another function. 04476 * 04477 * It can also call display functions to make sure the information is 04478 * correct - in this way, updates will not be done so often (like 04479 * for every ITEM command received), but less frequently but still 04480 * update the display fully. All the functions above are optimized to 04481 * only draw stuff that needs drawing. So calling them a lot is not 04482 * going to draw stuff too much. 04483 */ 04484 04485 void do_clearlock(void) { 04486 } 04487 04488 void x_set_echo(void) { 04489 gtk_entry_set_visibility(GTK_ENTRY(entrytext), !cpl.no_echo); 04490 } 04491 04492 void draw_info_windows(void) 04493 { 04494 if (draw_info_freeze1) { 04495 gtk_text_thaw (GTK_TEXT (gtkwin_info_text)); 04496 gtk_adjustment_set_value(GTK_ADJUSTMENT(text_vadj), GTK_ADJUSTMENT(text_vadj)->upper-GTK_ADJUSTMENT(text_vadj)->page_size); 04497 gtk_text_set_adjustments(GTK_TEXT (gtkwin_info_text),GTK_ADJUSTMENT(text_hadj),GTK_ADJUSTMENT(text_vadj)); 04498 draw_info_freeze1=FALSE; 04499 } 04500 if (draw_info_freeze2) { 04501 gtk_text_thaw (GTK_TEXT (gtkwin_info_text2)); 04502 gtk_adjustment_set_value(GTK_ADJUSTMENT(text_vadj2), GTK_ADJUSTMENT(text_vadj2)->upper-GTK_ADJUSTMENT(text_vadj2)->page_size); 04503 gtk_text_set_adjustments(GTK_TEXT (gtkwin_info_text2),GTK_ADJUSTMENT(text_hadj2),GTK_ADJUSTMENT(text_vadj2)); 04504 draw_info_freeze2=FALSE; 04505 } 04506 } 04507 04508 04509 /* X11 client doesn't care about this */ 04510 void client_tick(uint32 tick) 04511 { 04512 inventory_tick(); 04513 mapdata_animation(); 04514 #ifdef HAVE_SDL 04515 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) sdl_gen_map(0); 04516 else 04517 #endif 04518 gtk_draw_map(0); 04519 } 04520 04524 void client_pickup(uint32 pickup) 04525 { 04526 int menu; 04527 04528 /* Update value, so handling function won't resend info. */ 04529 pickup_mode = pickup; 04530 04531 for (menu = 0; menu < pickup_count; menu++) 04532 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pickup_menus[menu]), (pickup & pickup_value[menu]) ? 1 : 0); 04533 } 04534 04535 int do_timeout(void) { 04536 04537 updatelock=0; 04538 04539 if (!tick) { 04540 inventory_tick(); 04541 mapdata_animation(); 04542 } 04543 update_spell_list(0); 04544 draw_info_windows(); 04545 if (redraw_needed) { 04546 display_map_doneupdate(TRUE, FALSE); 04547 redraw_needed=FALSE; 04548 } 04549 if (cpl.showmagic) magic_map_flash_pos(); 04550 return TRUE; 04551 } 04552 04553 int gtk_checkchilds(void) { 04554 monitorChilds(); 04555 return FALSE; 04556 } 04557 04558 04559 04560 /* Here are the old Xutil commands needed. */ 04561 /* ----------------------------------------------------------------------------*/ 04562 04563 04564 /* This function draws the magic map in the game window. I guess if 04565 * we wanted to get clever, we could open up some other window or 04566 * something. 04567 * 04568 * A lot of this code was taken from server/xio.c But being all 04569 * the map data has been figured, it tends to be much simpler. 04570 */ 04571 void draw_magic_map(void) 04572 { 04573 04574 int x=0; 04575 int y=0; 04576 04577 GtkWidget *hbox; 04578 GtkWidget *closebutton; 04579 GtkStyle *style; 04580 04581 static GtkWidget *magicgtkpixmap; 04582 04583 04584 static GdkBitmap *magicgdkmask; 04585 04586 04587 if (!cpl.magicmap) { 04588 draw_info ("You have yet to cast magic map.",NDI_BLACK); 04589 return; 04590 } 04591 04592 if(!gtkwin_magicmap) { 04593 04594 gtkwin_magicmap = gtk_window_new (GTK_WINDOW_DIALOG); 04595 gtk_window_position (GTK_WINDOW (gtkwin_magicmap), GTK_WIN_POS_CENTER); 04596 gtk_widget_set_usize (gtkwin_magicmap,264,300); 04597 gtk_window_set_title (GTK_WINDOW (gtkwin_magicmap), "Magic map"); 04598 gtk_window_set_policy (GTK_WINDOW (gtkwin_magicmap), FALSE, FALSE, FALSE); 04599 04600 gtk_signal_connect (GTK_OBJECT (gtkwin_magicmap), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), >kwin_magicmap); 04601 04602 mapvbox = gtk_vbox_new(FALSE, 0); 04603 gtk_widget_set_usize (mapvbox,264,300); 04604 gtk_container_add (GTK_CONTAINER(gtkwin_magicmap),mapvbox); 04605 04606 style = gtk_widget_get_style(gtkwin_magicmap); 04607 gtk_widget_realize(mapvbox); 04608 04609 04610 magicgdkpixmap = gdk_pixmap_new(gtkwin_magicmap->window, 04611 264, 04612 264, 04613 -1); 04614 magicgtkpixmap= gtk_pixmap_new (magicgdkpixmap, magicgdkmask); 04615 gtk_box_pack_start (GTK_BOX (mapvbox),magicgtkpixmap, FALSE, FALSE, 0); 04616 gtk_widget_show (magicgtkpixmap); 04617 04618 hbox = gtk_hbox_new(FALSE, 2); 04619 04620 closebutton = gtk_button_new_with_label ("Close"); 04621 gtk_signal_connect_object (GTK_OBJECT (closebutton), "clicked", 04622 GTK_SIGNAL_FUNC(gtk_widget_destroy), 04623 GTK_OBJECT (gtkwin_magicmap)); 04624 gtk_box_pack_start (GTK_BOX (hbox), closebutton, TRUE, FALSE, 0); 04625 gtk_box_pack_start (GTK_BOX (mapvbox), hbox, FALSE, FALSE, 0); 04626 gtk_widget_show (closebutton); 04627 gtk_widget_show (hbox); 04628 04629 gtk_widget_show (mapvbox); 04630 gtk_widget_show (gtkwin_magicmap); 04631 04632 04633 gdk_color_parse("Black", &map_color[0]); 04634 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[0]); 04635 gdk_color_parse("White", &map_color[1]); 04636 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[1]); 04637 gdk_color_parse("Navy", &map_color[2]); 04638 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[2]); 04639 gdk_color_parse("Red", &map_color[3]); 04640 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[3]); 04641 gdk_color_parse("Orange", &map_color[4]); 04642 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[4]); 04643 gdk_color_parse("DodgerBlue", &map_color[5]); 04644 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[5]); 04645 gdk_color_parse("DarkOrange2", &map_color[6]); 04646 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[6]); 04647 gdk_color_parse("SeaGreen", &map_color[7]); 04648 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[7]); 04649 gdk_color_parse("DarkSeaGreen", &map_color[8]); 04650 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[8]); 04651 gdk_color_parse("Grey50", &map_color[9]); 04652 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[9]); 04653 gdk_color_parse("Sienna", &map_color[10]); 04654 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[10]); 04655 gdk_color_parse("Gold", &map_color[11]); 04656 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[11]); 04657 gdk_color_parse("Khaki", &map_color[12]); 04658 gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[12]); 04659 04660 04661 magic_map_gc = gdk_gc_new (magicgdkpixmap); 04662 04663 04664 gdk_gc_set_foreground (magic_map_gc, &map_color[0]); 04665 gdk_draw_rectangle (magicgdkpixmap, magic_map_gc, 04666 TRUE, 04667 0, 04668 0, 04669 264, 04670 264); 04671 cpl.mapxres = (262)/cpl.mmapx; 04672 cpl.mapyres = (262)/cpl.mmapy; 04673 if (cpl.mapxres < 1 || cpl.mapyres<1) { 04674 LOG(LOG_WARNING,"gtk::draw_magic_map","magic map resolution less than 1, map is %dx%d", 04675 cpl.mmapx, cpl.mmapy); 04676 return; 04677 } 04678 /* In theory, cpl.mapxres and cpl.mapyres do not have to be the same. However, 04679 * it probably makes sense to keep them the same value. 04680 * Need to take the smaller value. 04681 */ 04682 if (cpl.mapxres>cpl.mapyres) cpl.mapxres=cpl.mapyres; 04683 else cpl.mapyres=cpl.mapxres; 04684 04685 if (cpl.mapxres>24) { 04686 cpl.mapxres=24; 04687 cpl.mapyres=24; 04688 } 04689 /* This is keeping the same unpacking scheme that the server uses 04690 * to pack it up. 04691 */ 04692 for (y = 0; y < cpl.mmapy; y++) { 04693 for (x = 0; x < cpl.mmapx; x++) { 04694 uint8 val = cpl.magicmap[y*cpl.mmapx + x]; 04695 04696 gdk_gc_set_foreground (magic_map_gc, &map_color[val&FACE_COLOR_MASK]); 04697 04698 gdk_draw_rectangle (magicgdkpixmap, magic_map_gc, 04699 TRUE, 04700 2+cpl.mapxres*x, 04701 2+cpl.mapyres*y, 04702 cpl.mapxres, 04703 cpl.mapyres); 04704 } /* Saw into this space */ 04705 } 04706 /* gdk_gc_destroy (magic_map_gc);*/ 04707 gtk_widget_draw (mapvbox,NULL); 04708 } 04709 04710 else { 04711 /* ------------------ There is already a magic map up - replace it ---------*/ 04712 04713 gdk_window_raise (gtkwin_magicmap->window); 04714 /* --------------------------- */ 04715 04716 gdk_gc_set_foreground (magic_map_gc, &map_color[0]); 04717 gdk_draw_rectangle (magicgdkpixmap, magic_map_gc, 04718 TRUE, 04719 0, 04720 0, 04721 264, 04722 264); 04723 04724 cpl.mapxres = (262)/cpl.mmapx; 04725 cpl.mapyres = (262)/cpl.mmapy; 04726 if (cpl.mapxres < 1 || cpl.mapyres<1) { 04727 LOG(LOG_WARNING,"gtk::draw_magic_map","magic map resolution less than 1, map is %dx%d\n", 04728 cpl.mmapx, cpl.mmapy); 04729 return; 04730 } 04731 04732 if (cpl.mapxres>cpl.mapyres) cpl.mapxres=cpl.mapyres; 04733 else cpl.mapyres=cpl.mapxres; 04734 04735 04736 04737 if (cpl.mapxres>24) { 04738 cpl.mapxres=24; 04739 cpl.mapyres=24; 04740 } 04741 04742 04743 04744 for (y = 0; y < cpl.mmapy; y++) { 04745 for (x = 0; x < cpl.mmapx; x++) { 04746 uint8 val = cpl.magicmap[y*cpl.mmapx + x]; 04747 04748 gdk_gc_set_foreground (magic_map_gc, &map_color[val&FACE_COLOR_MASK]); 04749 04750 gdk_draw_rectangle (magicgdkpixmap, magic_map_gc, 04751 TRUE, 04752 2+cpl.mapxres*x, 04753 2+cpl.mapyres*y, 04754 cpl.mapxres, 04755 cpl.mapyres); 04756 04757 } 04758 04759 } 04760 gtk_widget_draw (mapvbox,NULL); 04761 } 04762 } 04763 04764 /* Basically, this just flashes the player position on the magic map */ 04765 04766 void magic_map_flash_pos(void) 04767 { 04768 if (!cpl.showmagic) return; 04769 if (!gtkwin_magicmap) return; 04770 cpl.showmagic ^=2; 04771 if (cpl.showmagic & 2) { 04772 gdk_gc_set_foreground (magic_map_gc, &map_color[0]); 04773 } else { 04774 gdk_gc_set_foreground (magic_map_gc, &map_color[1]); 04775 } 04776 gdk_draw_rectangle (magicgdkpixmap, magic_map_gc, 04777 TRUE, 04778 2+cpl.mapxres*cpl.pmapx, 04779 2+cpl.mapyres*cpl.pmapy, 04780 cpl.mapxres, 04781 cpl.mapyres); 04782 gtk_widget_draw (mapvbox,NULL); 04783 } 04784 04785 /* Gets a specified windows coordinates. This function is pretty much 04786 * an exact copy out of the server. 04787 */ 04788 04789 void get_window_coord(GtkWidget *win, 04790 int *x,int *y, 04791 int *wx,int *wy, 04792 int *w,int *h) 04793 { 04794 int tmp; 04795 gdk_window_get_geometry (win->window, x, y, w, h, &tmp); 04796 /* gdk_window_get_root_origin (win->window, wx, wy); */ 04797 /* gdk_window_get_deskrelative_origin (win->window, wx, wy); */ 04798 gdk_window_get_origin (win->window, wx, wy); 04799 *wx -= *x; 04800 *wy -= *y; 04801 } 04802 04803 04804 void save_winpos(void) 04805 { 04806 char savename[MAX_BUF],buf[MAX_BUF]; 04807 FILE *fp; 04808 int x,y,w,h,wx,wy; 04809 04810 if (!want_config[CONFIG_SPLITWIN]) 04811 sprintf(savename,"%s/.crossfire/gwinpos", getenv("HOME")); 04812 else 04813 sprintf(savename,"%s/.crossfire/winpos", getenv("HOME")); 04814 04815 if (!(fp=fopen(savename,"w"))) { 04816 sprintf(buf,"Unable to open %s, window positions not saved",savename); 04817 draw_info(buf,NDI_BLUE); 04818 return; 04819 } 04820 04821 get_window_coord(gtkwin_root, &x,&y, &wx,&wy,&w,&h); 04822 fprintf(fp,"win_game: %d %d %d %d\n", wx,wy, w, h); 04823 if (want_config[CONFIG_SPLITWIN]) { 04824 get_window_coord(gtkwin_stats, &x,&y, &wx,&wy,&w,&h); 04825 fprintf(fp,"win_stats: %d %d %d %d\n", wx,wy, w, h); 04826 get_window_coord(gtkwin_info, &x,&y, &wx,&wy,&w,&h); 04827 fprintf(fp,"win_info: %d %d %d %d\n", wx,wy, w, h); 04828 get_window_coord(gtkwin_inv, &x,&y, &wx,&wy,&w,&h); 04829 fprintf(fp,"win_inv: %d %d %d %d\n", wx,wy, w, h); 04830 get_window_coord(gtkwin_look, &x,&y, &wx,&wy,&w,&h); 04831 fprintf(fp,"win_look: %d %d %d %d\n", wx,wy, w, h); 04832 get_window_coord(gtkwin_message, &x,&y, &wx,&wy,&w,&h); 04833 fprintf(fp,"win_message: %d %d %d %d\n", wx,wy, w, h); 04834 } else { 04835 /* in non split mode, we really want the position of the 04836 * various panes. Current versions do not have a proper 04837 * way (ie, function call/macro) to do this - future 04838 * versions of gtk will have a gtk_paned_get_position. 04839 * That code basically does the same thing as what we 04840 * are doing below (version 1.3) 04841 */ 04842 fprintf(fp,"inv_hpane: %d\n", 04843 GTK_PANED(inv_hpane)->child1_size); 04844 fprintf(fp,"stat_info_hpane: %d\n", 04845 GTK_PANED(stat_info_hpane)->child1_size); 04846 fprintf(fp,"stat_game_vpane: %d\n", 04847 GTK_PANED(stat_game_vpane)->child1_size); 04848 fprintf(fp,"game_bar_vpane: %d\n", 04849 GTK_PANED(game_bar_vpane)->child1_size); 04850 fprintf(fp,"inv_look_vpane: %d\n", 04851 GTK_PANED(inv_look_vpane)->child1_size); 04852 if (use_config[CONFIG_SPLITINFO]) 04853 fprintf(fp,"info_vpane: %d\n", 04854 GTK_PANED(info_vpane)->child1_size); 04855 } 04856 fclose(fp); 04857 sprintf(buf,"Window positions saved to %s",savename); 04858 draw_info(buf,NDI_BLUE); 04859 } 04860 04861 04862 /* Reads in the winpos file created by the above function and sets the 04863 * the window positions appropriately. 04864 */ 04865 void set_window_pos(void) 04866 { 04867 gint wx=0; 04868 gint wy=0; 04869 gint w=0; 04870 gint h=0; 04871 04872 char buf[MAX_BUF],*cp; 04873 FILE *fp; 04874 04875 if (want_config[CONFIG_SPLITWIN]) 04876 sprintf(buf,"%s/.crossfire/winpos", getenv("HOME")); 04877 else 04878 sprintf(buf,"%s/.crossfire/gwinpos", getenv("HOME")); 04879 04880 if (!(fp=fopen(buf,"r"))) return; 04881 04882 while(fgets(buf,MAX_BUF-1, fp)!=NULL) { 04883 buf[MAX_BUF-1]='\0'; 04884 if (!(cp=strchr(buf,' '))) continue; 04885 *cp++='\0'; 04886 if (sscanf(cp,"%d %d %d %d",&wx,&wy,&w,&h)!=4) { 04887 gint pos = atoi(cp); 04888 if (pos == 0) continue; 04889 04890 if (!strcmp(buf, "inv_hpane:")) gtk_paned_set_position(GTK_PANED(inv_hpane),pos); 04891 else if (!strcmp(buf, "stat_info_hpane:")) gtk_paned_set_position(GTK_PANED(stat_info_hpane),pos); 04892 else if (!strcmp(buf, "stat_game_vpane:")) gtk_paned_set_position(GTK_PANED(stat_game_vpane),pos); 04893 else if (!strcmp(buf, "game_bar_vpane:")) gtk_paned_set_position(GTK_PANED(game_bar_vpane),pos); 04894 else if (!strcmp(buf, "inv_look_vpane:")) gtk_paned_set_position(GTK_PANED(inv_look_vpane),pos); 04895 else if (use_config[CONFIG_SPLITINFO] && !strcmp(buf, "info_vpane:")) gtk_paned_set_position(GTK_PANED(info_vpane),pos); 04896 else LOG(LOG_ERROR,"gtk::set_window_pos","Found bogus line in window position file:\n/%s/ /%s/", buf, cp); 04897 } else { 04898 if (!strcmp(buf,"win_game:")) { 04899 gdk_window_move_resize(gtkwin_root->window, wx, wy, w, h); 04900 continue; 04901 } 04902 if (!want_config[CONFIG_SPLITWIN]) { 04903 LOG(LOG_ERROR,"gtk::set_window_pos","Found bogus line in window position file:\n%s %s", buf, cp); 04904 continue; 04905 } 04906 if (!strcmp(buf,"win_stats:")) { 04907 gdk_window_move_resize(gtkwin_stats->window, wx, wy, w, h); 04908 } 04909 if (!strcmp(buf,"win_info:")) { 04910 gdk_window_move_resize(gtkwin_info->window, wx, wy, w, h); 04911 } 04912 if (!strcmp(buf,"win_inv:")) { 04913 gdk_window_move_resize(gtkwin_inv->window, wx, wy, w, h); 04914 } 04915 if (!strcmp(buf,"win_look:")) { 04916 gdk_window_move_resize(gtkwin_look->window, wx, wy, w, h); 04917 } 04918 if (!strcmp(buf,"win_message:")) { 04919 gdk_window_move_resize(gtkwin_message->window, wx, wy, w, h); 04920 } 04921 } /* else if split windows */ 04922 } /* while fgets */ 04923 fclose(fp); 04924 } 04925 04926 04927 04928 04929 /*********************************************************************** 04930 * 04931 * Here starts the X11 init functions. It will call other 04932 * functions that were grouped previously by window 04933 * 04934 ***********************************************************************/ 04935 04936 /* Usage routine. All clients should support server, port and 04937 * display options, with -pix and -xpm also suggested. -split 04938 * does not need to be supported - it is in this copy because 04939 * the old code supported it. 04940 */ 04941 04942 static void usage(const char *progname) 04943 { 04944 puts("Usage of crossfire-client-gtk:\n\n"); 04945 puts("-cache - Cache images for future use."); 04946 puts("-nocache - Do not cache images (default action)."); 04947 puts("-darkness - Enables darkness code (default)"); 04948 puts("-nodarkness - Disables darkness code"); 04949 puts("-display <name> - Use <name> instead if DISPLAY environment variable."); 04950 puts("-download_all_faces - Download all needed faces before play starts"); 04951 puts("-echo - Echo the bound commands"); 04952 puts("-noecho - Do not echo the bound commands (default)"); 04953 puts("-faceset <name> - Use faceset <name> if available"); 04954 puts("-fasttcpsend - Send data immediately to server, may increase bandwidth"); 04955 puts("-nofasttcpsend - Disables fasttcpsend"); 04956 puts("-fog - Enable fog of war code"); 04957 puts("-help - Display this message."); 04958 puts("-loglevel <val> - Set default logging level (0 is most verbose)"); 04959 puts("-iconscale %% - Set icon scale percentage"); 04960 puts("-mapscale %% - Set map scale percentage"); 04961 puts("-mapsize xXy - Set the mapsize to be X by Y spaces. (default 11x11)"); 04962 puts("-splash - Display the splash screen (default)"); 04963 puts("-nosplash - Don't display the splash screen (startup logo)"); 04964 puts("-popups - Use pop up windows for input (default)"); 04965 puts("-nopopups - Don't use pop up windows for input"); 04966 puts("-port <number> - Use port <number> instead of the standard port number"); 04967 puts("-sdl - Use sdl for drawing png (may not work on all hardware"); 04968 puts("-server <name> - Connect to <name> instead of localhost."); 04969 puts("-showicon - Print status icons in inventory window"); 04970 puts("-smooth - Enable smooth"); 04971 puts("-nosmooth - Disable smooth"); 04972 puts("-mapscroll - Enable mapscrolling by bitmap operations"); 04973 puts("-nomapscroll - Disable mapscrolling by bitmap operations"); 04974 puts("-sound - Enable sound output (default)."); 04975 puts("-nosound - Disable sound output."); 04976 puts("-sound_server <path> - Executable to use to play sounds."); 04977 puts("-resists <val> - Control look of resistances."); 04978 puts("-split - Use split windows."); 04979 puts("-splitinfo - Use two information windows, segregated by information type."); 04980 puts("-timemapredraw - Print out timing information for map generation"); 04981 puts("-triminfowindow - Trims size of information window(s)"); 04982 puts("-notriminfowindow - Do not trims size of information window(s) (default)"); 04983 puts("-updatekeycodes - Update the saved bindings for this keyboard."); 04984 04985 exit(0); 04986 } 04987 04988 /* init_windows: This initializes all the windows - it is an 04989 * interface routine. The command line arguments are passed to 04990 * this function to interpret. Note that it is not in fact 04991 * required to parse anything, but doing at least -server and 04992 * -port would be a good idea. 04993 * 04994 * This function returns 0 on success, nonzero on failure. 04995 */ 04996 04997 int init_windows(int argc, char **argv) 04998 { 04999 int on_arg=1; 05000 char *display_name=""; 05001 load_defaults(); 05002 05003 #ifndef WIN32 05004 strcpy(VERSION_INFO,"GTK Unix Client " FULL_VERSION); 05005 #else 05006 strcpy(VERSION_INFO,"GTK Win32 Client " FULL_VERSION); 05007 #endif 05008 /* Set this global so we get skill experience - gtk client can display 05009 * it, so lets get the info. 05010 */ 05011 want_skill_exp=1; 05012 for (on_arg=1; on_arg<argc; on_arg++) { 05013 if (!strcmp(argv[on_arg],"-cache")) { 05014 want_config[CONFIG_CACHE]= TRUE; 05015 continue; 05016 } 05017 else if (!strcmp(argv[on_arg],"-nocache")) { 05018 want_config[CONFIG_CACHE]= FALSE; 05019 continue; 05020 } 05021 else if (!strcmp(argv[on_arg],"-darkness")) { 05022 want_config[CONFIG_DARKNESS]= TRUE; 05023 continue; 05024 } 05025 else if (!strcmp(argv[on_arg],"-nodarkness")) { 05026 want_config[CONFIG_DARKNESS]= FALSE; 05027 continue; 05028 } 05029 else if (!strcmp(argv[on_arg],"-display")) { 05030 if (++on_arg == argc) { 05031 LOG(LOG_WARNING,"gtk::init_windows","-display requires a display name"); 05032 return 1; 05033 } 05034 display_name = argv[on_arg]; 05035 continue; 05036 } 05037 else if (!strcmp(argv[on_arg],"-download_all_faces")) { 05038 want_config[CONFIG_DOWNLOAD]= TRUE; 05039 continue; 05040 } 05041 else if (!strcmp(argv[on_arg],"-echo")) { 05042 want_config[CONFIG_ECHO]= TRUE; 05043 continue; 05044 } 05045 else if (!strcmp(argv[on_arg],"-noecho")) { 05046 want_config[CONFIG_ECHO]= FALSE; 05047 continue; 05048 } 05049 else if (!strcmp(argv[on_arg],"-faceset")) { 05050 if (++on_arg == argc) { 05051 LOG(LOG_WARNING,"gtk::init_windows","-faceset requires a faceset name/number"); 05052 return 1; 05053 } 05054 face_info.want_faceset = argv[on_arg]; 05055 continue; 05056 } 05057 else if( !strcmp( argv[on_arg],"-fog")) { 05058 want_config[CONFIG_FOGWAR]= TRUE; 05059 continue; 05060 } 05061 else if( !strcmp( argv[on_arg],"-nofog")) { 05062 want_config[CONFIG_FOGWAR]= FALSE; 05063 continue; 05064 } 05065 else if (!strcmp(argv[on_arg],"-help")) { 05066 usage(argv[0]); 05067 continue; 05068 } 05069 else if( !strcmp( argv[on_arg],"-iconscale")) { 05070 if (++on_arg == argc) { 05071 LOG(LOG_WARNING,"gtk::init_windows","-iconscale requires a percentage value"); 05072 return 1; 05073 } 05074 want_config[CONFIG_ICONSCALE] = atoi(argv[on_arg]); 05075 if (want_config[CONFIG_ICONSCALE] < 25 || want_config[CONFIG_ICONSCALE]>200) { 05076 LOG(LOG_WARNING,"gtk::init_windows","Valid range for -iconscale is 25 through 200"); 05077 want_config[CONFIG_ICONSCALE]=100; 05078 return 1; 05079 } 05080 continue; 05081 } 05082 else if( !strcmp( argv[on_arg],"-mapscale")) { 05083 if (++on_arg == argc) { 05084 LOG(LOG_WARNING,"gtk::init_windows","-mapscale requires a percentage value"); 05085 return 1; 05086 } 05087 want_config[CONFIG_MAPSCALE] = atoi(argv[on_arg]); 05088 if (want_config[CONFIG_MAPSCALE] < 25 || want_config[CONFIG_MAPSCALE]>200) { 05089 LOG(LOG_WARNING,"gtk::init_windows","Valid range for -mapscale is 25 through 200"); 05090 want_config[CONFIG_MAPSCALE]=100; 05091 return 1; 05092 } 05093 continue; 05094 } 05095 else if (!strcmp(argv[on_arg],"-mapsize")) { 05096 char *cp, x, y=0; 05097 if (++on_arg == argc) { 05098 LOG(LOG_WARNING,"gtk::init_windows","-mapsize requires a XxY value"); 05099 return 1; 05100 } 05101 x = atoi(argv[on_arg]); 05102 for (cp = argv[on_arg]; *cp!='\0'; cp++) 05103 if (*cp == 'x' || *cp == 'X') break; 05104 05105 if (*cp==0) { 05106 LOG(LOG_WARNING,"gtk::init_windows","-mapsize requires both and X and Y value (ie, XxY - note the\nx in between."); 05107 } else { 05108 y = atoi(cp+1); 05109 } 05110 if (x<9 || y<9) { 05111 LOG(LOG_WARNING,"gtk::init_windows","map size must be positive values of at least 9"); 05112 } else if (x>MAP_MAX_SIZE || y>MAP_MAX_SIZE) { 05113 LOG(LOG_WARNING,"gtk::init_windows","Map size can not be larger than %d x %d", MAP_MAX_SIZE, MAP_MAX_SIZE); 05114 05115 } else { 05116 want_config[CONFIG_MAPWIDTH]=x; 05117 want_config[CONFIG_MAPHEIGHT]=y; 05118 } 05119 continue; 05120 } 05121 else if (!strcmp(argv[on_arg],"-fasttcpsend")) { 05122 want_config[CONFIG_FASTTCP] = TRUE; 05123 continue; 05124 } 05125 else if (!strcmp(argv[on_arg],"-nofasttcpsend")) { 05126 want_config[CONFIG_FASTTCP] = FALSE; 05127 continue; 05128 } 05129 else if (!strcmp(argv[on_arg],"-popups")) { 05130 want_config[CONFIG_POPUPS] = TRUE; 05131 continue; 05132 } 05133 else if (!strcmp(argv[on_arg],"-nopopups")) { 05134 want_config[CONFIG_POPUPS] = FALSE; 05135 continue; 05136 } 05137 else if (!strcmp(argv[on_arg],"-port")) { 05138 if (++on_arg == argc) { 05139 LOG(LOG_WARNING,"gtk::init_windows","-port requires a port number"); 05140 return 1; 05141 } 05142 want_config[CONFIG_PORT] = atoi(argv[on_arg]); 05143 continue; 05144 } 05145 else if (!strcmp(argv[on_arg],"-sdl")) { 05146 #ifndef HAVE_SDL 05147 LOG(LOG_WARNING,"gtk::init_windows","client not compiled with sdl support. Ignoring -sdl"); 05148 #else 05149 want_config[CONFIG_DISPLAYMODE] = CFG_DM_SDL; 05150 #endif 05151 continue; 05152 } 05153 else if (!strcmp(argv[on_arg],"+sdl")) { 05154 want_config[CONFIG_DISPLAYMODE] = CFG_DM_PIXMAP; 05155 continue; 05156 } 05157 else if (!strcmp(argv[on_arg],"-server")) { 05158 if (++on_arg == argc) { 05159 LOG(LOG_WARNING,"gtk::init_windows","-server requires a host name"); 05160 return 1; 05161 } 05162 server = argv[on_arg]; 05163 continue; 05164 } 05165 else if (!strcmp(argv[on_arg],"-showicon")) { 05166 want_config[CONFIG_SHOWICON] = TRUE; 05167 continue; 05168 } 05169 else if (!strcmp(argv[on_arg],"-smooth")) { 05170 want_config[CONFIG_SMOOTH] = TRUE; 05171 } 05172 else if (!strcmp(argv[on_arg],"-nosmooth")) { 05173 want_config[CONFIG_SMOOTH] = FALSE; 05174 } 05175 else if (!strcmp(argv[on_arg],"-mapscroll")) { 05176 want_config[CONFIG_MAPSCROLL] = TRUE; 05177 } 05178 else if (!strcmp(argv[on_arg],"-nomapscroll")) { 05179 want_config[CONFIG_MAPSCROLL] = FALSE; 05180 } 05181 else if (!strcmp(argv[on_arg],"-sound")) { 05182 want_config[CONFIG_SOUND] = TRUE; 05183 continue; 05184 } 05185 else if (!strcmp(argv[on_arg],"-nosound")) { 05186 want_config[CONFIG_SOUND] = FALSE; 05187 continue; 05188 } 05189 else if (!strcmp(argv[on_arg],"-sound_server")) { 05190 if (++on_arg == argc) { 05191 LOG(LOG_WARNING,"gtk::init_windows","-sound_server requires an executable pathname"); 05192 return 1; 05193 } 05194 sound_server = argv[on_arg]; 05195 continue; 05196 } 05197 else if (!strcmp(argv[on_arg],"-split")) { 05198 want_config[CONFIG_SPLITWIN]=TRUE; 05199 continue; 05200 } 05201 else if (!strcmp(argv[on_arg],"-nosplit")) { 05202 want_config[CONFIG_SPLITWIN]=FALSE; 05203 continue; 05204 } 05205 else if (!strcmp(argv[on_arg],"-resists")) { 05206 if (++on_arg == argc) { 05207 LOG(LOG_WARNING,"gtk::init_windows","-resists requires a value"); 05208 return 1; 05209 } 05210 want_config[CONFIG_RESISTS]=atoi(argv[on_arg]); 05211 continue; 05212 } 05213 else if (!strcmp(argv[on_arg],"-loglevel")) { 05214 extern int MINLOG; 05215 05216 if (++on_arg == argc) { 05217 LOG(LOG_WARNING,"gtk::init_windows","-loglevel requires a value"); 05218 return 1; 05219 } 05220 MINLOG = atoi(argv[on_arg]); 05221 continue; 05222 } 05223 else if (!strcmp(argv[on_arg],"-splitinfo")) { 05224 want_config[CONFIG_SPLITINFO]=TRUE; 05225 continue; 05226 } 05227 else if (!strcmp(argv[on_arg],"-timemapredraw")) { 05228 time_map_redraw=TRUE; 05229 continue; 05230 } 05231 else if (!strcmp(argv[on_arg],"-triminfowindow")) { 05232 want_config[CONFIG_TRIMINFO] = TRUE; 05233 continue; 05234 } 05235 else if (!strcmp(argv[on_arg],"-notriminfowindow")) { 05236 want_config[CONFIG_TRIMINFO] = FALSE; 05237 continue; 05238 } 05239 else if (!strcmp(argv[on_arg],"-updatekeycodes")) { 05240 updatekeycodes=TRUE; 05241 continue; 05242 } 05243 else if (!strcmp(argv[on_arg],"-splash")) { 05244 want_config[CONFIG_SPLASH] = TRUE; 05245 continue; 05246 } 05247 else if (!strcmp(argv[on_arg],"-nosplash")) { 05248 want_config[CONFIG_SPLASH] = FALSE; 05249 continue; 05250 } 05251 else { 05252 LOG(LOG_WARNING,"gtk::init_windows","Do not understand option %s", argv[on_arg]); 05253 usage(argv[0]); 05254 return 1; 05255 } 05256 } 05257 05258 LOG(LOG_INFO,"Client Version",VERSION_INFO); 05259 05260 /* Now copy over the values just loaded */ 05261 for (on_arg=0; on_arg<CONFIG_NUMS; on_arg++) { 05262 use_config[on_arg] = want_config[on_arg]; 05263 } 05264 05265 image_size = DEFAULT_IMAGE_SIZE * use_config[CONFIG_ICONSCALE] / 100; 05266 map_image_size = DEFAULT_IMAGE_SIZE * use_config[CONFIG_MAPSCALE] / 100; 05267 map_image_half_size = DEFAULT_IMAGE_SIZE * use_config[CONFIG_MAPSCALE] / 200; 05268 itemlist_set_show_icon(&inv_list, use_config[CONFIG_SHOWICON]); 05269 if (!use_config[CONFIG_CACHE]) use_config[CONFIG_DOWNLOAD] = FALSE; 05270 05271 mapdata_init(); 05272 05273 /* Finished parsing all the command line options. Now start 05274 * working on the display. 05275 */ 05276 gargc=argc; 05277 gargv=argv; 05278 05279 for (on_arg = 0; on_arg<MAX_HISTORY; on_arg++) 05280 history[on_arg][0]=0; 05281 05282 05283 if (get_root_display(display_name,gargc,gargv)) 05284 return 1; 05285 05286 init_keys(); 05287 init_cache_data(); 05288 if (want_config[CONFIG_SPLASH]) destroy_splash(); 05289 gtk_timeout_add (10,(GtkFunction)gtk_checkchilds,NULL); 05290 return 0; 05291 } 05292 05293 05300 void display_map_doneupdate(int redraw, int notice) 05301 { 05302 if (notice) 05303 return; 05304 05305 if (updatelock < 30) { 05306 updatelock++; 05307 05308 #ifdef HAVE_SDL 05309 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) sdl_gen_map(redraw); 05310 else 05311 #endif 05312 gtk_draw_map(redraw); 05313 } /* if updatelock */ 05314 else { 05315 redraw_needed = TRUE; 05316 } 05317 } 05318 05319 void display_map_newmap(void) 05320 { 05321 reset_map(); 05322 } 05323 05324 void resize_map_window(int x, int y) 05325 { 05326 gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), map_image_size * x, map_image_size * y); 05327 if (!want_config[CONFIG_SPLITWIN]) { 05328 #if 0 05329 /* 15 it is a purely arbitary value. But basically, if the map window is 05330 * narrow, we then will have the stats on top, with message down below 05331 * the map window. IF the map window is wide, we put these side 05332 * by side at the top 05333 */ 05334 if (bigmap && x<15) { 05335 05336 /* reverse of below basically. */ 05337 GtkWidget *newpane; /* will take place of game_bar_vpane */ 05338 05339 bigmap =FALSE; 05340 05341 newpane = gtk_vpaned_new(); /*game in pane1, bars in pane2 */ 05342 05343 /* Remove referance to the split - the stats frame takes its place */ 05344 gtk_widget_ref(game_bar_vpane); 05345 gtk_container_remove(GTK_CONTAINER(stat_game_vpane), game_bar_vpane); 05346 05347 /* Stat now gets the entire top pane to itself */ 05348 gtk_widget_ref(stat_frame); 05349 gtk_container_remove(GTK_CONTAINER(game_bar_vpane), stat_frame); 05350 gtk_paned_add1(GTK_PANED(stat_game_vpane), stat_frame); 05351 gtk_widget_unref(stat_frame); 05352 05353 /* statbars now second part of bottom frame */ 05354 gtk_widget_ref(message_frame); 05355 gtk_container_remove(GTK_CONTAINER(game_bar_vpane), message_frame); 05356 gtk_paned_add2(GTK_PANED(newpane), message_frame); 05357 gtk_widget_unref(message_frame); 05358 05359 /* game now first part of bottom frame */ 05360 gtk_widget_ref(gameframe); 05361 gtk_container_remove(GTK_CONTAINER(stat_game_vpane), gameframe); 05362 gtk_paned_add1(GTK_PANED(newpane), gameframe); 05363 gtk_widget_unref(gameframe); 05364 05365 gtk_paned_add2(GTK_PANED(stat_game_vpane), newpane); 05366 05367 gtk_widget_show(newpane); 05368 /* This should also destroy it */ 05369 gtk_widget_unref(game_bar_vpane); 05370 game_bar_vpane = newpane; 05371 05372 } else if (!bigmap && x>=15) { 05373 05374 GtkWidget *newpane; /* will take place of game_bar_vpane */ 05375 bigmap=TRUE; 05376 newpane = gtk_hpaned_new(); 05377 05378 /* We need to remove this here - the game pane is goind to 05379 * take game_bar_vpane as second position in the stat_game_vpane. 05380 * add a refcount so it isn't destroyed. 05381 */ 05382 gtk_widget_ref(game_bar_vpane); 05383 gtk_container_remove(GTK_CONTAINER(stat_game_vpane), game_bar_vpane); 05384 05385 05386 /* Stat and message are now split on 'newpane' */ 05387 gtk_widget_ref(stat_frame); 05388 gtk_container_remove(GTK_CONTAINER(stat_game_vpane), stat_frame); 05389 gtk_paned_add1(GTK_PANED(newpane), stat_frame); 05390 gtk_widget_unref(stat_frame); 05391 05392 gtk_widget_ref(message_frame); 05393 gtk_container_remove(GTK_CONTAINER(game_bar_vpane), message_frame); 05394 gtk_paned_add2(GTK_PANED(newpane), message_frame); 05395 gtk_widget_unref(message_frame); 05396 05397 /* the game is now part 2 of stat_game_vpane, and not part of 05398 * game_bar_vpane 05399 */ 05400 05401 gtk_widget_ref(gameframe); 05402 gtk_container_remove(GTK_CONTAINER(game_bar_vpane), gameframe); 05403 gtk_paned_add2(GTK_PANED(stat_game_vpane), gameframe); 05404 gtk_widget_unref(gameframe); 05405 05406 /* Newpane (split stat/message) is now part one of stat_game_vpane */ 05407 gtk_paned_add1(GTK_PANED(stat_game_vpane), newpane); 05408 05409 gtk_widget_show(newpane); 05410 /* This should also destroy it */ 05411 gtk_widget_unref(game_bar_vpane); 05412 game_bar_vpane = newpane; 05413 } 05414 #endif 05415 gtk_widget_set_usize (gameframe, (map_image_size*use_config[CONFIG_MAPWIDTH])+6, (map_image_size*use_config[CONFIG_MAPHEIGHT])+6); 05416 } else { 05417 gtk_widget_set_usize (gtkwin_root,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,(map_image_size*use_config[CONFIG_MAPHEIGHT])+6); 05418 } 05419 05420 #ifdef HAVE_SDL 05421 if (use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL) 05422 init_SDL( drawingarea, FALSE); 05423 #endif 05424 05425 } 05426 05427 05428 void display_map_startupdate(void) 05429 { 05430 } 05431 05432 char *get_metaserver(void) 05433 { 05434 cpl.input_state = Metaserver_Select; 05435 05436 05437 while(cpl.input_state==Metaserver_Select) { 05438 /* 05439 * This gtk_main will be quit inside of event_callback 05440 * when the user enters data into the input_text box 05441 * at which point the input_state will change. 05442 */ 05443 gtk_main(); 05444 usleep(10*1000); /* 10 milliseconds */ 05445 } 05446 return cpl.input_text; 05447 } 05448 /*default log window to 200 lines of about 50 characters*/ 05449 #define MAX_LOG_CHARACTERS 10000 05450 void gtkLogListener (LogEntry *le){ 05451 if (bugtrack){ 05452 gtk_text_freeze (GTK_TEXT (bugtrack)); 05453 gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, getLogText(le), -1); 05454 printf ("current gtk len: %d\n",gtk_text_get_length(GTK_TEXT (bugtrack))); 05455 if (gtk_text_get_length(GTK_TEXT (bugtrack)) > MAX_LOG_CHARACTERS){ 05456 /*gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), TRUE);*/ 05457 guint toomuch =gtk_text_get_length(GTK_TEXT (bugtrack))-MAX_LOG_CHARACTERS; 05458 printf("Deleteing..%d\n",toomuch); 05459 gtk_text_set_point(GTK_TEXT (bugtrack),toomuch); 05460 gtk_text_backward_delete(GTK_TEXT (bugtrack),toomuch); 05461 gtk_text_set_point(GTK_TEXT (bugtrack),gtk_text_get_length(GTK_TEXT (bugtrack))); 05462 /* gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), FALSE);*/ 05463 } 05464 gtk_text_thaw (GTK_TEXT (bugtrack)); 05465 } 05466 } 05467 #define MAX_RECURSE 50 05468 /* a handler for the glib error logging. Used so we care ourself of the gtk/gdk warnings 05469 * and make them appear in message window using the logging facility 05470 */ 05471 void gLogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data){ 05472 static char LogOrigin[4096]; 05473 static int recurse = 0; 05474 LogLevel level; 05475 gboolean in_recursion; 05476 gboolean is_fatal; 05477 /*printf ("hi i received a g error on %s with severity %d and message %s\n",log_domain,log_level,message);*/ 05478 if (recurse > MAX_RECURSE) 05479 return; /*don't Log*/ 05480 if (recurse == MAX_RECURSE){ 05481 recurse++; 05482 LOG(LOG_ERROR,"gtk::gLogHandler","Too many recurse, reached limit: %d",recurse); 05483 recurse--; 05484 return; 05485 } 05486 LogOrigin[0]='\0'; 05487 strcat (LogOrigin,"Library::"); 05488 in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; 05489 is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; 05490 log_level &= G_LOG_LEVEL_MASK; 05491 05492 if (!message) 05493 message = "gLogHandler: (NULL) message"; 05494 if (log_domain){ 05495 strcat(LogOrigin,log_domain); 05496 strcat(LogOrigin,"-"); 05497 }else 05498 strcat(LogOrigin, "** "); 05499 05500 05501 switch (log_level) 05502 { 05503 case G_LOG_LEVEL_ERROR:/*Our critical*/ 05504 strcat (LogOrigin,"ERROR"); 05505 level=LOG_CRITICAL; 05506 break; 05507 case G_LOG_LEVEL_CRITICAL:/*our error*/ 05508 strcat (LogOrigin,"CRITICAL"); 05509 level=LOG_ERROR; 05510 break; 05511 case G_LOG_LEVEL_WARNING:/*our warning*/ 05512 strcat (LogOrigin,"WARNING"); 05513 level=LOG_WARNING; 05514 break; 05515 case G_LOG_LEVEL_MESSAGE:/* message */ 05516 strcat (LogOrigin,"Message"); 05517 level=LOG_INFO; 05518 break; 05519 case G_LOG_LEVEL_INFO:/* message */ 05520 strcat (LogOrigin,"Info"); 05521 level=LOG_INFO; 05522 break; 05523 case G_LOG_LEVEL_DEBUG:/*our debug*/ 05524 strcat (LogOrigin,"DEBUG"); 05525 level=LOG_DEBUG; 05526 break; 05527 default: 05528 strcat (LogOrigin,"LOG"); 05529 level=LOG_WARNING; 05530 break; 05531 } 05532 if (in_recursion) 05533 strcat(LogOrigin," (recursed)"); 05534 /*else 05535 strcat(LogOrigin,"**: ");*/ 05536 recurse++; 05537 LOG(level,LogOrigin,"%s",message); 05538 if (is_fatal) 05539 LOG(level,LogOrigin,"Last Message was fatal, aborting..."); 05540 recurse--; 05541 } 05542 05543 05544 extern const char* cached_server_file; 05545 05546 int main(int argc, char *argv[]) 05547 { 05548 int got_one=0; 05549 static char file_cache[ MAX_BUF ]; 05550 05551 g_log_set_handler (NULL,G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR| 05552 G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO| 05553 G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL); 05554 g_log_set_handler ("Gtk",G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR| 05555 G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO| 05556 G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL); 05557 g_log_set_handler ("Gdk",G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR| 05558 G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO| 05559 G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL); 05560 05561 /* This needs to be done first. In addition to being quite quick, 05562 * it also sets up some paths (client_libdir) that are needed by 05563 * the other functions. 05564 */ 05565 init_client_vars(); 05566 05567 /* Override ../common/init.c default for POPUPS for this client only 05568 * because when compiled with --enable-cfgtk2, a player is not able to 05569 * login to the server if POPUPS are disabled. See bug # 2022488 at 05570 * http://sourceforge.net/tracker/index.php?func=detail&aid=2022488&group_id=13833&atid=113833 05571 */ 05572 want_config[CONFIG_POPUPS] = TRUE; 05573 05574 05575 snprintf( file_cache, MAX_BUF, "%s/.crossfire/servers.cache", getenv( "HOME" ) ); 05576 cached_server_file = file_cache; 05577 init_text_callbacks(); 05578 setLogListener(gtkLogListener); 05579 /* Call this very early. It should parse all command 05580 * line arguments and set the pertinent ones up in 05581 * globals. Also call it early so that if it can't set up 05582 * the windowing system, we get an error before trying to 05583 * to connect to the server. And command line options will 05584 * likely change on the server we connect to. 05585 */ 05586 if (init_windows(argc, argv)) { /* x11.c */ 05587 LOG(LOG_CRITICAL,"gtk::main","Failure to init windows."); 05588 exit(1); 05589 } 05590 05591 csocket.inbuf.buf=malloc(MAXSOCKBUF); 05592 05593 #ifdef WIN32 /* def WIN32 */ 05594 maxfd = 0; /* This is ignored on win32 platforms */ 05595 05596 /* This is required for sockets to be used under win32 */ 05597 { 05598 WORD Version = 0x0202; 05599 WSADATA wsaData; 05600 if (WSAStartup( Version, &wsaData ) != 0) { 05601 LOG(LOG_CRITICAL,"gtk::main", "Couldn't load winsock!"); 05602 exit(1); 05603 } 05604 } 05605 #else /* def WIN32 */ 05606 #ifdef HAVE_SYSCONF 05607 maxfd = sysconf(_SC_OPEN_MAX); 05608 #else 05609 maxfd = getdtablesize(); 05610 #endif 05611 #endif /* def WIN32 */ 05612 05613 if (init_sounds() == -1) 05614 use_config[CONFIG_SOUND] = FALSE; 05615 else use_config[CONFIG_SOUND] = TRUE; 05616 05617 /* Loop to connect to server/metaserver and play the game */ 05618 while (1) { 05619 reset_client_vars(); 05620 csocket.inbuf.len=0; 05621 csocket.cs_version=0; 05622 05623 /* Perhaps not the best assumption, but we are taking it that 05624 * if the player has not specified a server (ie, server 05625 * matches compiled in default), we use the metaserver. 05626 * otherwise, use the server provided, bypassing metaserver. 05627 * Also, if the player has already played on a server once (defined 05628 * by got_one), go to the metaserver. That gives them the opportunity 05629 * to quit the client or select another server. We should really add 05630 * an entry for the last server there also. 05631 */ 05632 05633 if (!server || got_one) { 05634 char *ms; 05635 metaserver_get_info(meta_server, meta_port); 05636 metaserver_show(TRUE); 05637 do { 05638 draw_info_windows(); 05639 ms=get_metaserver(); 05640 } while (metaserver_select(ms)); 05641 negotiate_connection(use_config[CONFIG_SOUND]); 05642 } else { 05643 csocket.fd=init_connection(server, use_config[CONFIG_PORT]); 05644 if (csocket.fd == -1) { /* specified server no longer valid */ 05645 server = NULL; 05646 continue; 05647 } 05648 negotiate_connection(use_config[CONFIG_SOUND]); 05649 } 05650 05651 got_one=1; 05652 event_loop(); 05653 /* if event_loop has exited, we most of lost our connection, so we 05654 * loop again to establish a new one. 05655 */ 05656 05657 mapdata_reset(); 05658 /* Need to reset the images so they match up properly and prevent 05659 * memory leaks. 05660 */ 05661 reset_image_data(); 05662 remove_item_inventory(cpl.ob); 05663 remove_item_inventory(cpl.below); 05664 set_look_list_env(cpl.below); 05665 } 05666 exit(0); /* never reached */ 05667 }