Crossfire Client, Branches  R11627
gx11.c
Go to the documentation of this file.
1 const char * const rcsid_gtk_gx11_c =
2  "$Id: gx11.c 9581 2008-07-20 00:54:34Z kbulgrien $";
3 /*
4  Crossfire client, a client program for the crossfire program.
5 
6  Copyright (C) 2001-2003,2006-2007 Mark Wedel & Crossfire Development Team
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  The author can be reached via e-mail to crossfire-devel@real-time.com
23 */
24 
25 /*
26  * This file contains the core window code.
27  */
28 
29 /* Most functions in this file are private. Here is a list of
30  * the global functions:
31  *
32  * draw_color_info(int color, char*buf) - draws text in specified color
33  * draw_info - draw info in the info window
34  * end_windows - used when exiting
35  * init_windows - called when starting up
36  * load_images - creates the bitmaps and pixmaps (if being used)
37  * create_pixmap - creates a pixmap from given file and assigns to
38  * the given face
39  * create_xpm - as create_pixmap, but does an XPM image
40  * load_additional_images - loads images that have been downloaded
41  * from the server in prior sessions
42  *
43  * draw_stats(int) - draws the stat window. Pass 1 to redraw all
44  * stats, not only those that changed
45  *
46  * draw_message_window(int) - draws the message window. Pass 1 to redraw
47  * all the bars, not only those that changed.
48  *
49  * NOTE: create_pixmap and create_xpm can be empty functions if the
50  * client will always use fonts - in that case, it should never
51  * request Bitmap or Pixmap data, and thus not need the create
52  * functions above
53  *
54  * Only functions in this file should be calling functions like
55  * draw_stats and draw_message_window with redraw set - functions
56  * in other files should always pass 0, because they will never have
57  * the information of whether a redraw is needed.
58  */
59 
60 
61 #include <config.h>
62 
63 #include <errno.h>
64 
65 /* gtk */
66 #include <gtk/gtk.h>
67 #ifndef WIN32
68 #include <gdk/gdkx.h>
69 #else
70 #include <gdk/gdkwin32.h>
71 #endif
72 #include <gdk/gdkkeysyms.h>
73 
74 #ifdef HAVE_SDL
75 #include <SDL.h>
76 #include <SDL_image.h>
77 #endif
78 
79 /* Always include our local headers after the system headers are included */
80 #include "client.h"
81 /*#include "clientbmap.h"*/
82 #include "item.h"
83 #include "pixmaps/crossfiretitle.xpm"
84 #include "gx11.h"
85 #include "gtkproto.h"
86 #include <script.h>
87 #include <p_cmd.h>
88 #include <time.h>
89 
90 #include "mapdata.h"
91 
92 
93 #ifdef HAVE_SDL
94 /* These are only used in SDL mode at current time */
95 extern SDL_Surface* mapsurface;
96 #endif
97 
98 static const char *const colorname[] = {
99 "Black", /* 0 */
100 "White", /* 1 */
101 "Navy", /* 2 */
102 "Red", /* 3 */
103 "Orange", /* 4 */
104 "DodgerBlue", /* 5 */
105 "DarkOrange2", /* 6 */
106 "SeaGreen", /* 7 */
107 "DarkSeaGreen", /* 8 */ /* Used for window background color */
108 "Grey50", /* 9 */
109 "Sienna", /* 10 */
110 "Gold", /* 11 */
111 "Khaki" /* 12 */
112 };
113 
114 #define DEFAULT_IMAGE_SIZE 32
115 
119 
120 
121  /* Copy from server: include/define.h */
122 #define PU_NOTHING 0x00000000
123 
124 #define PU_DEBUG 0x10000000
125 #define PU_INHIBIT 0x20000000
126 #define PU_STOP 0x40000000
127 #define PU_NEWMODE 0x80000000
128 
129 #define PU_RATIO 0x0000000F
130 
131 #define PU_FOOD 0x00000010
132 #define PU_DRINK 0x00000020
133 #define PU_VALUABLES 0x00000040
134 #define PU_BOW 0x00000080
135 
136 #define PU_ARROW 0x00000100
137 #define PU_HELMET 0x00000200
138 #define PU_SHIELD 0x00000400
139 #define PU_ARMOUR 0x00000800
140 
141 #define PU_BOOTS 0x00001000
142 #define PU_GLOVES 0x00002000
143 #define PU_CLOAK 0x00004000
144 #define PU_KEY 0x00008000
145 
146 #define PU_MISSILEWEAPON 0x00010000
147 #define PU_ALLWEAPON 0x00020000
148 #define PU_MAGICAL 0x00040000
149 #define PU_POTION 0x00080000
150 
151 #define PU_SPELLBOOK 0x00100000
152 #define PU_SKILLSCROLL 0x00200000
153 #define PU_READABLES 0x00400000
154 #define PU_MAGIC_DEVICE 0x00800000
155 
156 #define PU_NOT_CURSED 0x01000000
157 #define PU_JEWELS 0x02000000
158 #define PU_FLESH 0x04000000
159 
160 
161 
162 typedef struct {
163  GtkWidget *playername;
164  GtkWidget *score;
165  GtkWidget *level;
166  GtkWidget *hp;
167  GtkWidget *sp;
168  GtkWidget *gr;
169  GtkWidget *Str;
170  GtkWidget *Dex;
171  GtkWidget *Con;
172  GtkWidget *Int;
173  GtkWidget *Wis;
174  GtkWidget *Cha;
175  GtkWidget *Pow;
176  GtkWidget *wc;
177  GtkWidget *dam;
178  GtkWidget *ac;
179  GtkWidget *armor;
180  GtkWidget *speed;
181  GtkWidget *food;
182  GtkWidget *skill;
183  GtkWidget *skill_exp[MAX_SKILL*2];
184 } StatWindow;
185 
186 static char **gargv;
187 
188 #define MAX_HISTORY 50
189 #define MAX_COMMAND_LEN 256
192 
193 extern int maxfd;
194 struct timeval timeout;
195 static gint csocket_fd = 0;
196 
197 static int gargc;
198 
199 static uint8
200  bigmap=FALSE; /* True if we've moved some windows around for big maps */
201 
202 uint8
206 
207 
208 /* Default size of scroll buffers is 100 K */
211 
212 
213 typedef struct {
214  int x;
215  int y;
216 } MapPos;
217 
218 
219 /* vitals window */
220 
221 typedef struct {
222  GtkWidget *bar;
223  GtkStyle *style[2];
224  int state;
225 } Vitals;
226 
227 static Vitals vitals[4];
228 GtkWidget *run_label, *fire_label;
229 static GtkWidget *restable; /* resistance table */
230 static GtkWidget *res_scrolled_window; /* window the resistances are in */
231 static GtkWidget *skill_scrolled_window; /* window the skills are in */
232 
233 
234 static GtkWidget *resists[NUM_RESISTS];
236 
237 GdkColor gdk_green = { 0, 0, 0xcfff, 0 };
238 GdkColor gdk_red = { 0, 0xcfff, 0, 0 };
239 GdkColor gdk_grey = { 0, 0xea60, 0xea60, 0xea60 };
240 GdkColor gdk_black = { 0, 0, 0, 0 };
241 
242 static GdkColor map_color[16];
243 /* Not static so it can be used in inventory.c for highlighting. */
244 GdkColor root_color[16];
245 static GdkPixmap *magicgdkpixmap;
246 static GdkGC *magic_map_gc;
247 static GtkWidget *mapvbox;
248 GdkPixmap *mapwindow;
249 GdkBitmap *dark1, *dark2, *dark3;
250 GdkPixmap *dark;
251 
252 GtkTooltips *tooltips;
253 
254 static GtkWidget *dialogtext;
255 static GtkWidget *dialog_window;
256 GtkWidget *drawingarea;
257 
258 GdkGC *mapgc;
259 
260 GtkWidget *cclist;
262 
263 enum {
267 };
268 
269 
270 GtkWidget *entrytext; /* "Command-line" frame, built in get_info_display(). */
271 static GtkObject *text_hadj,*text_vadj;
272 static GtkObject *text_hadj2,*text_vadj2;
273 static GtkWidget *gameframe, *stat_frame, *message_frame;
274 
276 /* gtk */
277 
279 GtkWidget *gtkwin_info_text; /* Referenced by inventory::count_callback. */
280 GtkWidget *gtkwin_info_text2; /* Used when CONFIG_SPLITINFO */
282 
283 
284 static GtkWidget *gtkwin_about = NULL;
285 static GtkWidget *gtkwin_bug = NULL;
286 static GtkWidget *gtkwin_splash = NULL;
287 static GtkWidget *gtkwin_shelp = NULL;
288 static GtkWidget *gtkwin_magicmap = NULL;
289 
290 static GtkWidget *bugtrack = NULL;
291 
292 /* These are the panes used in splitting up the window in non root
293  * windows mode. Need to be globals so we can get/set the
294  * information when loading/saving the positions.
295  */
296 
297 static GtkWidget
298  *inv_hpane, /* Split between inv,message window and stats/game/.. window */
299  *stat_info_hpane, /* Game/stats on left, info windows on right */
300  *stat_game_vpane, /* Status window/game window split */
301  *game_bar_vpane, /* Game/scroll split */
302  *inv_look_vpane, /* Inventory/look split */
303  *info_vpane; /* Split for 2 info windows */
304 
305 static char *last_str;
306 
308 static unsigned int pickup_mode = 0;
309 
310 int updatelock = 0;
311 
312 /* This is used for caching the images across runs. When we get a face
313  * command from the server, we check the facecache for that name. If
314  * so, we can then use the num to find out what face number it is on the
315  * local side.
316  */
317 struct FaceCache {
318  char *name;
321 
322 int misses=0,total=0;
323 
324 void disconnect(GtkWidget *widget);
325 
326 /* Called from disconnect command - that closes the socket -
327  * we just need to do the gtk cleanup.
328  */
329 void cleanup_connection(void) {
330  if (csocket_fd) {
331  gdk_input_remove(csocket_fd);
332  csocket_fd=0;
333  gtk_main_quit();
334  }
336 }
337 
338 /* Main loop iteration related stuff */
339 static void do_network(void) {
340  fd_set tmp_read;
341  int pollret;
342  extern int updatelock;
343 
344  if (csocket.fd==-1) {
345  if (csocket_fd) {
346  gdk_input_remove(csocket_fd);
347  csocket_fd=0;
348  gtk_main_quit();
349  }
350  return;
351  }
352 
353  if (updatelock < 20) {
354  FD_ZERO(&tmp_read);
355  FD_SET(csocket.fd, &tmp_read);
356  script_fdset(&maxfd,&tmp_read);
357  pollret = select(maxfd, &tmp_read, NULL, NULL, &timeout);
358  if (pollret==-1) {
359  LOG(LOG_WARNING,"gtk::do_network", "Got errno %d on select call.", errno);
360  }
361  else if ( pollret>0 ) {
362  if (FD_ISSET(csocket.fd, &tmp_read)) {
363  DoClient(&csocket);
364 #ifndef WIN32
365  if ( pollret > 1 ) script_process(&tmp_read);
366 #endif
367  }
368  else {
369  script_process(&tmp_read);
370  }
371  }
372  } else {
373  LOG(LOG_INFO,"gtk::do_network","locked for network recieves.\n");
374  }
375  if (csocket.fd==-1) {
376  if (csocket_fd) {
377  gdk_input_remove(csocket_fd);
378  csocket_fd=0;
379  gtk_main_quit();
380  }
381  return;
382  }
383 
384 }
385 
386 #ifdef WIN32 /* Win32 scripting support */
387 int do_scriptout(void)
388 {
389  script_process(NULL);
390  return(TRUE);
391 }
392 #endif /* WIN32 */
393 
394 static void event_loop(void)
395 {
396  gint fleep;
397  extern int do_timeout(void); /* forward */
398  int tag;
399 
400  if (MAX_TIME==0) {
401  timeout.tv_sec = 0;
402  timeout.tv_usec = 0;
403  }
404  maxfd = csocket.fd + 1;
405 
406  if (MAX_TIME!=0) {
407  timeout.tv_sec = 0;/* MAX_TIME / 1000000;*/
408  timeout.tv_usec = 0;/* MAX_TIME % 1000000;*/
409  }
410 
411  fleep = gtk_timeout_add (100,
412  (GtkFunction) do_timeout,
413  NULL);
414 
415 #ifdef WIN32
416  gtk_timeout_add (25, (GtkFunction) do_scriptout, NULL);
417 #endif
418 
419  csocket_fd = gdk_input_add ((gint) csocket.fd,
420  GDK_INPUT_READ,
421  (GdkInputFunction) do_network, &csocket);
422  tag = csocket_fd;
423 
424  gtk_main();
425  gtk_timeout_remove(tag);
426 
428  LOG(LOG_INFO,"gtk::event_loop","gtk_main exited, returning from event_loop");
429 }
430 
431 
432 
433 
434 /* Handle mouse presses in the game window */
435 
436 static void button_map_event(GtkWidget *widget, GdkEventButton *event) {
437  int dx, dy, i, x, y, xmidl, xmidh, ymidl, ymidh;
438 
439  x=(int)event->x;
440  y=(int)event->y;
444  xmidh=(use_config[CONFIG_MAPWIDTH]/2 + 1) * map_image_size;
446  ymidh=(use_config[CONFIG_MAPHEIGHT]/2 + 1) * map_image_size;
447 
448  switch (event->button) {
449  case 1:
450  look_at(dx,dy);
451  break;
452 
453  case 2:
454  case 3:
455  if (x<xmidl)
456  i = 0;
457  else if (x>xmidh)
458  i = 6;
459  else i =3;
460 
461  if (y>ymidh)
462  i += 2;
463  else if (y>ymidl)
464  i++;
465 
466  if (event->button==2) {
467  switch (i) {
468  case 0: fire_dir (8);break;
469  case 1: fire_dir (7);break;
470  case 2: fire_dir (6);break;
471  case 3: fire_dir (1);break;
472  case 5: fire_dir (5);break;
473  case 6: fire_dir (2);break;
474  case 7: fire_dir (3);break;
475  case 8: fire_dir (4);break;
476  }
477  /* Only want to fire once */
478  clear_fire();
479  }
480  else switch (i) {
481  case 0: move_player (8);break;
482  case 1: move_player (7);break;
483  case 2: move_player (6);break;
484  case 3: move_player (1);break;
485  case 5: move_player (5);break;
486  case 6: move_player (2);break;
487  case 7: move_player (3);break;
488  case 8: move_player (4);break;
489  }
490  }
491 }
492 
493 
494 
495 
496 
497 /******************************************************************************
498  *
499  * Code related to face caching.
500  *
501  *****************************************************************************/
502 
503 /* Initializes the data for image caching */
504 static void init_cache_data(void)
505 {
506  int i;
507  GtkStyle *style;
508 #include "pixmaps/question.xpm"
509 
510 
511  LOG(LOG_INFO,"gtk::init_cache_data","Init Cache");
512 
513  style = gtk_widget_get_style(gtkwin_root);
514  pixmaps[0] = malloc(sizeof(PixmapInfo));
515  pixmaps[0]->icon_image = gdk_pixmap_create_from_xpm_d(gtkwin_root->window,
516  (GdkBitmap**)&pixmaps[0]->icon_mask,
517  &style->bg[GTK_STATE_NORMAL],
518  (gchar **)question_xpm);
519 #ifdef HAVE_SDL
521  /* Make a semi transparent question mark symbol to
522  * use for the cached images.
523  */
524 #include "pixmaps/question.sdl"
525  pixmaps[0]->map_image = SDL_CreateRGBSurfaceFrom(question_sdl,
526  32, 32, 1, 4, 1, 1, 1, 1);
527  SDL_SetAlpha(pixmaps[0]->map_image, SDL_SRCALPHA, 70);
528  pixmaps[0]->fog_image = SDL_CreateRGBSurfaceFrom(question_sdl,
529  32, 32, 1, 4, 1, 1, 1, 1);
530  SDL_SetAlpha(pixmaps[0]->fog_image, SDL_SRCALPHA, 70);
531  }
532  else
533 #endif
534  {
535  pixmaps[0]->map_image = pixmaps[0]->icon_image;
536  pixmaps[0]->fog_image = pixmaps[0]->icon_image;
537  pixmaps[0]->map_mask = pixmaps[0]->icon_mask;
538  }
539  pixmaps[0]->icon_width = pixmaps[0]->icon_height = pixmaps[0]->map_width = pixmaps[0]->map_height = map_image_size;
540  pixmaps[0]->smooth_face = 0;
541 
542  /* Don't do anything special for SDL image - rather, that drawing
543  * code will check to see if there is no data
544  */
545 
546  /* Initialize all the images to be of the same value. */
547  for (i=1; i<MAXPIXMAPNUM; i++) {
548  pixmaps[i] = pixmaps[0];
549  }
550 
552 }
553 
554 /* Deals with command history. If direction is 0, we are going backwards,
555  * if 1, we are moving forward.
556  */
557 
558 void gtk_command_history(int direction)
559 {
561  if (direction) {
562  i--;
563  if (i<0) i+=MAX_HISTORY;
564  if (i == cur_history_position) return;
565  } else {
566  i++;
567  if (i>=MAX_HISTORY) i = 0;
568  if (i == cur_history_position) {
569  /* User has forwarded to what should be current entry - reset it now. */
570  gtk_entry_set_text(GTK_ENTRY(entrytext), "");
571  gtk_entry_set_position(GTK_ENTRY(entrytext), 0);
573  return;
574  }
575  }
576 
577  if (history[i][0] == 0) return;
578 
580 /* fprintf(stderr,"resetting postion to %d, data = %s\n", i, history[i]);*/
581  gtk_entry_set_text(GTK_ENTRY(entrytext), history[i]);
582  gtk_entry_set_position(GTK_ENTRY(entrytext), strlen(history[i]));
583  gtk_widget_grab_focus (GTK_WIDGET(entrytext));
585 }
586 
588 {
589  const gchar *entry_text, *newcommand;
590 
591  entry_text = gtk_entry_get_text(GTK_ENTRY(entrytext));
592  newcommand = complete_command(entry_text);
593  /* Value differ, so update window */
594  if (newcommand != NULL) {
595  /* Set position to last character */
596  gtk_entry_set_text(GTK_ENTRY(entrytext), newcommand);
597  }
598  else
599  /* Grab focus anyway, key can be used somewhere, prevent other handlers */
600  gtk_widget_grab_focus (GTK_WIDGET(entrytext));
601  gtk_entry_set_position(GTK_ENTRY(entrytext), -1);
602 }
603 
604 
605 /* Event handlers for map drawing area */
606 /* For a reason I don't know, this gets called a whole bunch.
607  * every time a monster is killed, this gets called for a reason
608  * I can't figure out.
609  */
610 
611 static gint
612 configure_event (GtkWidget *widget, GdkEventConfigure *event)
613 {
614  static sint16 ox=-1, oy=-1;
615 
616  /* Handle the surplus number of events that this causes to be generated.
617  * Basically, if the size of the window hasn't changed, we really don't
618  * care - position of the window isn't important.
619  * Note that we could be more clever and free up the other data even on
620  * requests that do change the size,
621  * but this will fix the most horrendous memory leak
622  */
623  if (event->type == GDK_CONFIGURE) {
624  if (((GdkEventConfigure*)event)->width == ox && ((GdkEventConfigure*)event)->height == oy)
625  return TRUE;
626  else {
627 #if 0
628  fprintf(stderr, "ox=%d != %d, oy=%d != %d\n", ox, ((GdkEventConfigure*)event)->width,
629  oy, ((GdkEventConfigure*)event)->height);
630 #endif
631  ox = ((GdkEventConfigure*)event)->width;
632  oy = ((GdkEventConfigure*)event)->height;
633  }
634  }
635 
636 #ifdef HAVE_SDL
638  /* When program first runs, mapsurface can be null.
639  * Either way, we want to catch it here.
640  */
641  if (mapsurface)
642  SDL_UpdateRect( mapsurface, 0, 0, 0, 0);
643  return TRUE;
644  }
645 #endif
646 
647  mapgc = gdk_gc_new (drawingarea->window);
648 
650  int x,y,count;
651  GdkGC *darkgc;
652 
653  /* This is used when drawing with GdkPixmaps. Create another surface,
654  * as well as some light/dark images
655  */
656  dark = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, -1);
657  gdk_draw_rectangle(dark, drawingarea->style->black_gc, TRUE, 0, 0, map_image_size, map_image_size);
658  dark1 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1);
659  dark2 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1);
660  dark3 = gdk_pixmap_new(drawingarea->window, map_image_size, map_image_size, 1);
661 
662  /* We need our own GC here because we are working with single bit depth images */
663  darkgc = gdk_gc_new(dark1);
664  gdk_gc_set_foreground(darkgc, &root_color[NDI_WHITE]);
665  /* Clear any garbage values we get when we create the bitmaps */
666  gdk_draw_rectangle(dark1, darkgc, TRUE, 0, 0, map_image_size, map_image_size);
667  gdk_draw_rectangle(dark2, darkgc, TRUE, 0, 0, map_image_size, map_image_size);
668  gdk_draw_rectangle(dark3, darkgc, TRUE, 0, 0, map_image_size, map_image_size);
669  gdk_gc_set_foreground(darkgc, &root_color[NDI_BLACK]);
670  count=0;
671  for (x=0; x<map_image_size; x++) {
672  for (y=0; y<map_image_size; y++) {
673 
674  /* We just fill in points every X pixels - dark1 is the darkest, dark3 is the lightest.
675  * dark1 has 50% of the pixels filled in, dark2 has 33%, dark3 has 25%
676  * The formulae here are not perfect - dark2 will not match perfectly with an
677  * adjacent dark2 image. dark3 results in diagonal stripes. OTOH, these will
678  * change depending on the image size.
679  */
680  if ((x+y) % 2) {
681  gdk_draw_point(dark1, darkgc, x, y);
682  }
683  if ((x+y) %3) {
684  gdk_draw_point(dark2, darkgc, x, y);
685  }
686  if ((x+y) % 4) {
687  gdk_draw_point(dark3, darkgc, x, y);
688  }
689  /* dark1 gets filled on 0x01, 0x11, 0x10, only leaving 0x00 empty */
690  }
691  /* If the row size is even, we put an extra value in count - in this
692  * way, the pixels will be even on one line, odd on the next, etc
693  * instead of vertical lines - at least for dark1 and dark3
694  */
695  }
696  mapwindow = gdk_pixmap_new(gtkwin_root->window, use_config[CONFIG_MAPWIDTH] * map_image_size, use_config[CONFIG_MAPHEIGHT] * map_image_size, -1);
697  gdk_gc_unref(darkgc);
698  }
700  return TRUE;
701 }
702 
703 
704 
705 /* Redraw the screen from the backing pixmap */
706 static gint
707 expose_event (GtkWidget *widget, GdkEventExpose *event)
708 {
709 #ifdef HAVE_SDL
710  if(use_config[CONFIG_DISPLAYMODE]==CFG_DM_SDL && mapsurface) {
711  SDL_UpdateRect( mapsurface, 0, 0, 0, 0);
712  return FALSE;
713  }
714 #endif
716  return FALSE;
717 }
718 
719 /*
720  * Sets up player game view window, implemented as a gtk table. Cells are initialized
721  * with the bg.xpm pixmap to avoid resizes and to initialize GC's and everything for the
722  * actual drawing routines later.
723  */
724 
725 static int get_game_display(GtkWidget *frame) {
726  GtkWidget *gtvbox, *gthbox;
727 
728  gtvbox = gtk_vbox_new (FALSE, 0);
729  gtk_container_add (GTK_CONTAINER (frame), gtvbox);
730  gthbox = gtk_hbox_new (FALSE, 0);
731  gtk_box_pack_start (GTK_BOX (gtvbox), gthbox, FALSE, FALSE, 1);
732 
733  drawingarea = gtk_drawing_area_new();
735  /* Add mouseclick events to the drawing area */
736 
737  gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);
738 
739  /* Set up X redraw routine signalling */
740  gtk_signal_connect (GTK_OBJECT (drawingarea), "expose_event",
741  (GtkSignalFunc) expose_event, NULL);
742  gtk_signal_connect (GTK_OBJECT(drawingarea),"configure_event",
743  (GtkSignalFunc) configure_event, NULL);
744  /* Set up handling of mouseclicks in map */
745 
746  gtk_signal_connect (GTK_OBJECT(drawingarea),
747  "button_press_event",
748  GTK_SIGNAL_FUNC(button_map_event),
749  NULL);
750 
751  /* Pack it up and show it */
752 
753  gtk_box_pack_start (GTK_BOX (gthbox), drawingarea, FALSE, FALSE, 1);
754 
755  gtk_widget_show(drawingarea);
756 
757  gtk_widget_show(gthbox);
758  gtk_widget_show(gtvbox);
759 
760 
761  gtk_signal_connect (GTK_OBJECT (frame), "expose_event",
762  (GtkSignalFunc) expose_event, NULL);
763  gtk_signal_connect (GTK_OBJECT(frame),"configure_event",
764  (GtkSignalFunc) configure_event, NULL);
765 
766  gtk_widget_show (frame);
767  return 0;
768 }
769 
770 
771 
772 /******************************************************************************
773  *
774  * The functions dealing with the info window follow
775  *
776  *****************************************************************************/
777 
778 
779 static void enter_callback(GtkWidget *widget, GtkWidget *entry)
780 {
781  const gchar *entry_text;
782 
783  /* Next reply will reset this as necessary */
784  gtk_entry_set_visibility(GTK_ENTRY(entrytext), TRUE);
785 
786  entry_text = gtk_entry_get_text(GTK_ENTRY(entrytext));
787  /* printf("Entry contents: %s\n", entry_text);*/
788 
790  strcpy(cpl.input_text, entry_text);
791  } else if (cpl.input_state == Reply_One ||
794  strcpy(cpl.input_text, entry_text);
795  if (cpl.input_state == Reply_One)
796  cpl.input_text[1] = 0;
797 
799 
800  } else {
802  /* No reason to do anything for a null string */
803  if (entry_text[0] != 0) {
804  strncpy(history[cur_history_position], entry_text, MAX_COMMAND_LEN);
806  cur_history_position++;
807  cur_history_position %= MAX_HISTORY;
809  extended_command(entry_text);
810  }
811  }
812  gtk_entry_set_text(GTK_ENTRY(entrytext),"");
813  gtk_widget_grab_focus (GTK_WIDGET(gtkwin_info_text));
814 
816  {
818  /* This is the gtk_main that is started up by get_metaserver
819  * The client will start another one once it is connected
820  * to a crossfire server
821  */
822  gtk_main_quit();
823  }
824 }
825 
826 /* Can use a wheeled mouse to scroll the info window */
827 static gboolean
828 info_text_button_press_event (GtkWidget *widget, GdkEventButton *event,
829  gpointer user_data)
830 {
831  GtkAdjustment *vadj;
832  gboolean shifted;
833  gfloat v_value;
834 
835  vadj = GTK_TEXT (widget)->vadj;
836  v_value = vadj->value;
837 
838  shifted = (event->state & GDK_SHIFT_MASK) != 0;
839 
840  switch (event->button)
841  {
842  case 4:
843  if (shifted)
844  v_value -= vadj->page_size;
845  else
846  v_value -= vadj->step_increment * 5;
847  break;
848 
849  case 5:
850  if (shifted)
851  v_value += vadj->page_size;
852  else
853  v_value += vadj->step_increment * 5;
854  break;
855 
856  default:
857  return FALSE;
858  }
859 
860  v_value = CLAMP (v_value, vadj->lower, vadj->upper - vadj->page_size);
861 
862  gtk_adjustment_set_value (vadj, v_value);
863 
864  return TRUE;
865 }
866 
867 static int get_info_display(GtkWidget *frame) {
868  GtkWidget *box1;
869  GtkWidget *box2;
870  GtkWidget *tablet;
871  GtkWidget *vscrollbar;
872  FILE *infile;
873 
874  box1 = gtk_vbox_new (FALSE, 0);
876  info_vpane = gtk_vpaned_new();
877  gtk_container_add (GTK_CONTAINER (frame), info_vpane);
878  gtk_widget_show(info_vpane);
879  gtk_paned_add2(GTK_PANED(info_vpane), box1);
880  } else {
881  gtk_container_add (GTK_CONTAINER (frame), box1);
882  }
883  gtk_widget_show (box1);
884 
885  box2 = gtk_vbox_new (FALSE, 3);
886  gtk_container_border_width (GTK_CONTAINER (box2), 3);
887  gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
888  gtk_widget_show (box2);
889 
890 
891  tablet = gtk_table_new (2, 2, FALSE);
892  gtk_table_set_row_spacing (GTK_TABLE (tablet), 0, 2);
893  gtk_table_set_col_spacing (GTK_TABLE (tablet), 0, 2);
894  gtk_box_pack_start (GTK_BOX (box2), tablet, TRUE, TRUE, 0);
895  gtk_widget_show (tablet);
896 
897  text_hadj = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40);
898  text_vadj = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40);
899 
900  gtkwin_info_text = gtk_text_new (GTK_ADJUSTMENT(text_hadj),GTK_ADJUSTMENT(text_vadj));
901  gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), FALSE);
902  gtk_table_attach (GTK_TABLE (tablet), gtkwin_info_text, 0, 1, 0, 1,
903  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
904  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
905  gtk_widget_show (gtkwin_info_text);
906 
907 
908  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (gtkwin_info_text)->vadj);
909  gtk_table_attach (GTK_TABLE (tablet), vscrollbar, 1, 2, 0, 1,
910  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
911  gtk_widget_show (vscrollbar);
912 
913  gtk_signal_connect (GTK_OBJECT (gtkwin_info_text), "button_press_event",
914  GTK_SIGNAL_FUNC (info_text_button_press_event),
915  vscrollbar);
916 
917  gtk_text_freeze (GTK_TEXT (gtkwin_info_text));
918 
919  gtk_widget_realize (gtkwin_info_text);
920 
921  if (use_config[CONFIG_SPLITINFO]) {
922 
923  box1 = gtk_vbox_new (FALSE, 0);
924  gtk_widget_show (box1);
925  gtk_paned_add1(GTK_PANED(info_vpane), box1);
926 
927  tablet = gtk_table_new (2, 2, FALSE);
928  gtk_table_set_row_spacing (GTK_TABLE (tablet), 0, 2);
929  gtk_table_set_col_spacing (GTK_TABLE (tablet), 0, 2);
930  gtk_box_pack_start (GTK_BOX (box1), tablet, TRUE, TRUE, 0);
931  gtk_widget_show (tablet);
932 
933  text_hadj2 = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40);
934  text_vadj2 = gtk_adjustment_new(1, 0, 1, 0.01, 0.1, 40);
935 
936  gtkwin_info_text2 = gtk_text_new (GTK_ADJUSTMENT(text_hadj2),GTK_ADJUSTMENT(text_vadj2));
937 
938  gtk_text_set_editable (GTK_TEXT (gtkwin_info_text2), FALSE);
939  gtk_table_attach (GTK_TABLE (tablet), gtkwin_info_text2, 0, 1, 0, 1,
940  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
941  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
942  gtk_widget_show (gtkwin_info_text2);
943 
944  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (gtkwin_info_text2)->vadj);
945  gtk_table_attach (GTK_TABLE (tablet), vscrollbar, 1, 2, 0, 1,
946  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
947  gtk_widget_show (vscrollbar);
948  gtk_signal_connect (GTK_OBJECT (gtkwin_info_text2), "button_press_event",
949  GTK_SIGNAL_FUNC (info_text_button_press_event),
950  vscrollbar);
951 
952  gtk_widget_realize (gtkwin_info_text2);
953  }
954 
955  infile = fopen("Welcome", "r");
956 
957  if (infile)
958  {
959  char buffer[1024];
960  int nchars;
961 
962  while (1)
963  {
964  nchars = fread(buffer, 1, 1024, infile);
965  gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, NULL,
966  NULL, buffer, nchars);
967 
968  if (nchars < 1024)
969  break;
970  }
971 
972  fclose (infile);
973  }
974 
975  gtk_text_thaw (GTK_TEXT (gtkwin_info_text));
976 
977 
978  entrytext = gtk_entry_new ();
979  gtk_signal_connect(GTK_OBJECT(entrytext), "activate",
980  GTK_SIGNAL_FUNC(enter_callback),
981  entrytext);
982  gtk_box_pack_start (GTK_BOX (box2),entrytext, FALSE, TRUE, 0);
983  GTK_WIDGET_SET_FLAGS (entrytext, GTK_CAN_DEFAULT);
984  gtk_widget_grab_default (entrytext);
985  gtk_widget_show (entrytext);
986 
987  return 0;
988 }
989 
990 /* Various replies */
991 
992 static void sendstr(char *sendstr)
993 {
994  gtk_widget_destroy (dialog_window);
995  send_reply(sendstr);
997 }
998 
999 
1000 /* This is similar to draw_info below, but doesn't advance to a new
1001  * line. Generally queries use this function to draw the prompt for
1002  * the name, password, etc.
1003  */
1004 
1005 
1006 
1007 static void dialog_callback(GtkWidget *dialog)
1008 {
1009  const gchar *dialog_text;
1010  dialog_text = gtk_entry_get_text(GTK_ENTRY(dialogtext));
1011  send_reply(dialog_text);
1012  gtk_widget_destroy (dialog_window);
1014 }
1015 static GtkWidget *userText = NULL;
1016 static GtkWidget *passwordText = NULL;
1017 static GtkWidget *passwordText2 = NULL;
1018 static GtkWidget *loginWindow = NULL;
1019 static GtkWidget *motdText = NULL;
1020 static GtkWidget *rulesText = NULL;
1021 static GtkWidget *newsText = NULL;
1022 static GtkWidget *loginTabs = NULL;
1023 static GtkWidget *loginButtonOk = NULL;
1024 static GtkWidget *loginButtonCancel = NULL;
1025 static GtkWidget *loginMessage = NULL;
1026 
1027 char password[64]="";
1028 static void setUserPass(GtkButton *button, gpointer func_data) {
1029  gchar* user;
1030  gchar* pass;
1031  user=gtk_editable_get_chars (GTK_EDITABLE(userText),0,-1);
1032  pass=gtk_editable_get_chars (GTK_EDITABLE(passwordText),0,-1);
1033  strncpy(password,pass,sizeof(password));
1034  send_reply(user);
1035 #ifdef MULTKEYS
1036  /* Now is a good time to load player's specific key bindings */
1037  if (csocket.servername != NULL)
1038  sprintf(cpl.name, "%s.%s", user, csocket.servername);
1039  else
1040  strcpy( cpl.name, user );
1041  init_keys( );
1042 #endif
1044  g_free(user);
1045  g_free(pass);
1046  gtk_widget_hide(loginWindow);
1047 }
1048 static void confirmUserPass(GtkButton *button, gpointer func_data) {
1049  gchar* pass;
1050  pass=gtk_editable_get_chars (GTK_EDITABLE(passwordText2),0,-1);
1051  send_reply(pass);
1053  g_free(pass);
1054  gtk_widget_hide(loginWindow);
1055 }
1056 static void cancelConnection(GtkButton *button, gpointer func_data) {
1057  gtk_widget_hide(loginWindow);
1059  disconnect(GTK_WIDGET(button));
1060 }
1061 
1062 static void disable_ok_if_empty(gpointer button, GtkEditable *entry) {
1063  gchar *passcontent,*txtcontent;
1064  txtcontent = gtk_editable_get_chars(GTK_EDITABLE(userText),0,-1);
1065  passcontent= gtk_editable_get_chars(GTK_EDITABLE(passwordText) ,0,-1);
1066  if ( passcontent && txtcontent &&
1067  (strlen(txtcontent)>=1)&&
1068  (strlen(passcontent)>=1))
1069  gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),TRUE);
1070  else
1071  gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),FALSE);
1072  if (txtcontent && (strlen (txtcontent)>0))
1073  gtk_widget_show(passwordText);
1074  else
1075  gtk_widget_hide(passwordText);
1076  g_free(txtcontent);
1077  g_free(passcontent);
1078 }
1079 static void change_focus(GtkWidget *focusTo, GtkEditable *entry) {
1080 
1081  char *txtcontent = gtk_editable_get_chars(entry,0,-1);
1082 /* printf("switch focus\n"); */
1083  if (txtcontent && (strlen(txtcontent)>0))
1084  gtk_widget_grab_focus(focusTo);
1085 }
1086 static void activate_ok_if_not_empty(GtkWidget *button, GtkEditable *entry) {
1087  char *txtcontent = gtk_editable_get_chars(entry,0,-1);
1088  if (txtcontent && (strlen(txtcontent)>0))
1089  gtk_widget_activate(button);
1090  if (txtcontent)
1091  g_free(txtcontent);
1092 }
1093 static void fill_news(GtkWidget *o, news_entry *news) {
1094  media_state state;
1095  while(news){
1096  state = write_media(GTK_TEXT(o),"[b]");
1097  write_media_with_state(GTK_TEXT(o),news->title,state);
1098  write_media(GTK_TEXT(o),"\n\n");
1099  write_media(GTK_TEXT(o),news->content);
1100  write_media(GTK_TEXT(o),"\n\n");
1101  news=news->next;
1102  }
1103 }
1104 static gint dialog_delete_event_callback(GtkWidget *widget, GdkEvent *event, gpointer data)
1105  {
1106  loginWindow = NULL;
1107  return FALSE;
1108  }
1109 static void buildLoginDialog(void) {
1110  if (loginWindow==NULL){
1111  /* Build window */
1112  GtkWidget *vbox, *table, *label, *hbox, *vscroll;
1113  loginWindow= gtk_window_new(GTK_WINDOW_TOPLEVEL);
1114  gtk_window_set_policy (GTK_WINDOW (loginWindow), TRUE, TRUE,
1115  FALSE);
1116  gtk_window_set_transient_for (GTK_WINDOW (loginWindow),
1117  GTK_WINDOW (gtkwin_root));
1118  gtk_window_set_title (GTK_WINDOW (loginWindow), "Login");
1119  gtk_window_set_transient_for(GTK_WINDOW (loginWindow),
1120  GTK_WINDOW (gtkwin_root));
1121  vbox=gtk_vbox_new(FALSE,4);
1122 
1123  /* Build it's notebook */
1124  loginTabs = gtk_notebook_new();
1125  /* notebook -> news */
1126  hbox=gtk_hbox_new(FALSE,2);
1127  newsText = gtk_text_new(NULL,NULL);
1128  gtk_text_set_word_wrap(GTK_TEXT(newsText),TRUE);
1129  gtk_text_set_line_wrap(GTK_TEXT(newsText),TRUE);
1130  vscroll = gtk_vscrollbar_new (GTK_TEXT (newsText)->vadj);
1131  gtk_box_pack_start(GTK_BOX(hbox),newsText,TRUE,TRUE,0);
1132  gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0);
1133  label = gtk_label_new("News");
1134  gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),hbox,label);
1135  gtk_widget_show(vscroll);
1136  gtk_widget_show(newsText);
1137  gtk_widget_show(hbox);
1138  /* notebook -> rules */
1139  hbox=gtk_hbox_new(FALSE,2);
1140  rulesText = gtk_text_new(NULL,NULL);
1141  gtk_text_set_word_wrap(GTK_TEXT(rulesText),TRUE);
1142  gtk_text_set_line_wrap(GTK_TEXT(rulesText),TRUE);
1143  vscroll = gtk_vscrollbar_new (GTK_TEXT (rulesText)->vadj);
1144  gtk_box_pack_start(GTK_BOX(hbox),rulesText,TRUE,TRUE,0);
1145  gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0);
1146  label = gtk_label_new("Rules");
1147  gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),hbox,label);
1148  gtk_widget_show(vscroll);
1149  gtk_widget_show(rulesText);
1150  gtk_widget_show(hbox);
1151 
1152  /* notebook -> login */
1153  hbox=gtk_hbox_new(FALSE,2);
1154  motdText = gtk_text_new(NULL,NULL);
1155  vscroll = gtk_vscrollbar_new (GTK_TEXT (motdText)->vadj);
1156  gtk_box_pack_start(GTK_BOX(hbox),motdText,TRUE,TRUE,0);
1157  gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,TRUE,0);
1158  gtk_widget_show(hbox);
1159  gtk_widget_show(motdText);
1160  gtk_widget_show(vscroll);
1161  gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0);
1162 
1163 
1164  /* Message information */
1165  loginMessage = gtk_label_new(NULL);
1166  gtk_box_pack_start(GTK_BOX(vbox),loginMessage,FALSE,FALSE,0);
1167  gtk_widget_show(loginMessage);
1168 
1169  /* user-pass table*/
1170  table=gtk_table_new(3,2,FALSE);
1171  /* TODO for strange reason justify does not work.
1172  * May someone fix this?*/
1173  label=gtk_label_new("User:");
1174  gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,GTK_EXPAND|GTK_FILL,0,2,2);
1175  gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT);
1176  gtk_widget_show(label);
1177  label=gtk_label_new("Password:");
1178  gtk_table_attach(GTK_TABLE(table),label,0,1,1,2,GTK_EXPAND|GTK_FILL,0,2,2);
1179  gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT);
1180  gtk_widget_show(label);
1181  label=gtk_label_new("Re-type password:");
1182  gtk_table_attach(GTK_TABLE(table),label,0,1,2,3,GTK_EXPAND|GTK_FILL,0,2,2);
1183  gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_RIGHT);
1184  gtk_widget_show(label);
1185  userText=gtk_entry_new();
1186  gtk_widget_show(userText);
1187  gtk_table_attach(GTK_TABLE(table),userText,1,2,0,1,GTK_EXPAND|GTK_FILL,0,2,2);
1188  passwordText= gtk_entry_new();
1189  gtk_entry_set_visibility(GTK_ENTRY(passwordText),FALSE);
1190  gtk_widget_show(passwordText);
1191  gtk_table_attach(GTK_TABLE(table),passwordText,1,2,1,2,GTK_EXPAND|GTK_FILL,0,2,2);
1192  passwordText2= gtk_entry_new();
1193  gtk_entry_set_visibility(GTK_ENTRY(passwordText2),FALSE);
1194  gtk_entry_set_editable(GTK_ENTRY(passwordText2),FALSE);
1195  gtk_table_attach(GTK_TABLE(table),passwordText2,1,2,2,3,GTK_EXPAND|GTK_FILL,0,2,2);
1196  gtk_widget_show(passwordText2);
1197  gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0);
1198 
1199 
1200  hbox=gtk_hbox_new(FALSE,2);
1201  loginButtonOk = gtk_button_new_with_label("Ok");
1202  loginButtonCancel = gtk_button_new_with_label("Cancel");
1203  gtk_box_pack_start(GTK_BOX(hbox),loginButtonOk,TRUE,FALSE,0);
1204  gtk_box_pack_start(GTK_BOX(hbox),loginButtonCancel,TRUE,FALSE,0);
1205  gtk_widget_show(hbox);
1206  gtk_widget_show(loginButtonOk);
1207  gtk_widget_show(loginButtonCancel);
1208 
1209  /* Manage events on login widgets */
1210  gtk_signal_connect_object (GTK_OBJECT (loginWindow),
1211  "delete_event",
1212  GTK_SIGNAL_FUNC (dialog_delete_event_callback),
1213  NULL);
1214  gtk_signal_connect_object (GTK_OBJECT (loginButtonCancel),
1215  "clicked",
1216  GTK_SIGNAL_FUNC (cancelConnection),
1217  NULL);
1218  gtk_signal_connect_object (GTK_OBJECT (userText),
1219  "changed",
1220  GTK_SIGNAL_FUNC (disable_ok_if_empty),
1221  GINT_TO_POINTER(loginButtonOk));
1222  gtk_signal_connect_object (GTK_OBJECT (passwordText),
1223  "changed",
1224  GTK_SIGNAL_FUNC (disable_ok_if_empty),
1225  GINT_TO_POINTER(loginButtonOk));
1226  gtk_signal_connect_object (GTK_OBJECT (userText),
1227  "activate",
1228  GTK_SIGNAL_FUNC (change_focus),
1229  GINT_TO_POINTER(passwordText));
1230  gtk_signal_connect_object (GTK_OBJECT (userText),
1231  "activate",
1232  GTK_SIGNAL_FUNC (change_focus),
1233  GINT_TO_POINTER(passwordText));
1234  gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
1235  gtk_signal_connect_object (GTK_OBJECT (passwordText),
1236  "activate",
1237  GTK_SIGNAL_FUNC (activate_ok_if_not_empty),
1238  GINT_TO_POINTER(loginButtonOk));
1239  gtk_signal_connect_object (GTK_OBJECT (passwordText2),
1240  "activate",
1241  GTK_SIGNAL_FUNC (activate_ok_if_not_empty),
1242  GINT_TO_POINTER(loginButtonOk));
1243  gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
1244  gtk_widget_show(table);
1245  gtk_widget_show(vbox);
1246  label=gtk_label_new("login");
1247  gtk_notebook_append_page(GTK_NOTEBOOK(loginTabs),vbox,label);
1248  gtk_container_add(GTK_CONTAINER(loginWindow),loginTabs);
1249  gtk_widget_show(loginTabs);
1250  gtk_window_set_default_size(GTK_WINDOW(loginWindow),500,400);
1251  gtk_window_set_position(GTK_WINDOW(loginWindow),GTK_WIN_POS_CENTER);
1252  }
1253  gtk_editable_delete_text(GTK_EDITABLE(motdText),0,-1);
1254  write_media(GTK_TEXT(motdText), getMOTD());
1255  gtk_editable_delete_text(GTK_EDITABLE(rulesText),0,-1);
1256  write_media(GTK_TEXT(rulesText),get_rules());
1257  gtk_editable_delete_text(GTK_EDITABLE(newsText),0,-1);
1258  fill_news(newsText,get_news());
1259  gtk_widget_show(loginWindow);
1260 }
1262 static void logUserIn(void) {
1263  buildLoginDialog();
1264  gtk_label_set_text(GTK_LABEL(loginMessage),"Type in user name and password");
1265  gtk_entry_set_editable(GTK_ENTRY(userText),TRUE);
1266  gtk_entry_set_editable(GTK_ENTRY(passwordText),TRUE);
1267  gtk_entry_set_editable(GTK_ENTRY(passwordText2),FALSE);
1268  gtk_widget_show(GTK_WIDGET(passwordText));
1269  gtk_widget_hide(GTK_WIDGET(passwordText2));
1270  if (signalLoginDialogClicked!=-1)
1271  gtk_signal_disconnect(GTK_OBJECT (loginButtonOk),
1272  signalLoginDialogClicked);
1273  signalLoginDialogClicked = gtk_signal_connect_object (GTK_OBJECT (loginButtonOk),
1274  "clicked",
1275  GTK_SIGNAL_FUNC (setUserPass),
1276  NULL);
1277  gtk_widget_set_sensitive(GTK_WIDGET(loginButtonOk),TRUE);
1278  gtk_entry_set_text(GTK_ENTRY(userText),"");
1279  gtk_entry_set_text(GTK_ENTRY(passwordText),"");
1280  gtk_entry_set_text(GTK_ENTRY(passwordText2),"");
1281  gtk_widget_grab_focus(userText);
1282 }
1283 static void sendPassword(void) {
1284  send_reply(password);
1286 }
1287 static void confirmPassword(void) {
1288  buildLoginDialog();
1289  gtk_label_set_text(GTK_LABEL(loginMessage),"Creating new user, please confirm password");
1290  gtk_entry_set_editable(GTK_ENTRY(userText),FALSE);
1291  gtk_entry_set_editable(GTK_ENTRY(passwordText),FALSE);
1292  gtk_entry_set_editable(GTK_ENTRY(passwordText2),TRUE);
1293  gtk_widget_hide(GTK_WIDGET(passwordText));
1294  gtk_widget_show(GTK_WIDGET(passwordText2));
1295  if (signalLoginDialogClicked!=-1)
1296  gtk_signal_disconnect(GTK_OBJECT (loginButtonOk),
1297  signalLoginDialogClicked);
1298  signalLoginDialogClicked = gtk_signal_connect_object (GTK_OBJECT (loginButtonOk),
1299  "clicked",
1300  GTK_SIGNAL_FUNC (confirmUserPass),
1301  NULL);
1302  gtk_widget_grab_focus(passwordText2);
1303 }
1304 /* Draw a prompt dialog window */
1305 /* Ok, now this is trying to be smart and decide what sort of dialog is
1306  * wanted.
1307  */
1308 
1309 void
1310 draw_prompt (const char *str)
1311 {
1312  GtkWidget *dbox;
1313  GtkWidget *hbox;
1314  GtkWidget *dialoglabel;
1315  GtkWidget *yesbutton, *nobutton;
1316  GtkWidget *strbutton, *dexbutton, *conbutton, *intbutton, *wisbutton,
1317  *powbutton, *chabutton;
1318 
1319  gint found = FALSE;
1320 
1321  if (!use_config[CONFIG_POPUPS])
1322  {
1323  draw_info(str, NDI_BLACK);
1324  }
1325  else
1326  {
1327  dialog_window = gtk_window_new (GTK_WINDOW_DIALOG);
1328 
1329  gtk_window_set_policy (GTK_WINDOW (dialog_window), TRUE, TRUE,
1330  FALSE);
1331  gtk_window_set_title (GTK_WINDOW (dialog_window), "Dialog");
1332  gtk_window_set_transient_for (GTK_WINDOW (dialog_window),
1333  GTK_WINDOW (gtkwin_root));
1334 
1335  dbox = gtk_vbox_new (FALSE, 6);
1336  gtk_container_add (GTK_CONTAINER (dialog_window), dbox);
1337 
1338  /* Ok, here we start generating the contents */
1339 
1340  /* printf ("Last info draw: %s\n", last_str); */
1341  while (!found)
1342  {
1343  if (!strcmp (str, ":"))
1344  {
1345  if (!strcmp (last_str, "What is your name?"))
1346  {
1347  logUserIn();
1348  return;
1349  }
1350 
1351  if (!strcmp (last_str, "What is your password?"))
1352  {
1353  sendPassword();
1354  return;
1355  }
1356  if (!strcmp
1357  (last_str, "Please type your password again."))
1358  {
1359  confirmPassword();
1360  return;
1361  }
1362  }
1363  /* Ok, tricky ones. */
1364  if (!strcmp (last_str, "[1-7] [1-7] to swap stats.")
1365  || !strncmp (last_str, "Str d", 5)
1366  || !strncmp (last_str, "Dex d", 5)
1367  || !strncmp (last_str, "Con d", 5)
1368  || !strncmp (last_str, "Int d", 5)
1369  || !strncmp (last_str, "Wis d", 5)
1370  || !strncmp (last_str, "Pow d", 5)
1371  || !strncmp (last_str, "Cha d", 5))
1372  {
1373 
1374  dialoglabel =
1375  gtk_label_new ("Roll again or exchange ability.");
1376  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1377  TRUE, 6);
1378  gtk_widget_show (dialoglabel);
1379 
1380  hbox = gtk_hbox_new (TRUE, 2);
1381  strbutton = gtk_button_new_with_label ("Str");
1382  gtk_box_pack_start (GTK_BOX (hbox), strbutton, TRUE,
1383  TRUE, 1);
1384  gtk_signal_connect_object (GTK_OBJECT (strbutton),
1385  "clicked",
1386  GTK_SIGNAL_FUNC (sendstr),
1387  GINT_TO_POINTER ("1"));
1388 
1389 
1390  dexbutton = gtk_button_new_with_label ("Dex");
1391  gtk_box_pack_start (GTK_BOX (hbox), dexbutton, TRUE,
1392  TRUE, 1);
1393  gtk_signal_connect_object (GTK_OBJECT (dexbutton),
1394  "clicked",
1395  GTK_SIGNAL_FUNC (sendstr),
1396  GINT_TO_POINTER ("2"));
1397 
1398  conbutton = gtk_button_new_with_label ("Con");
1399  gtk_box_pack_start (GTK_BOX (hbox), conbutton, TRUE,
1400  TRUE, 1);
1401  gtk_signal_connect_object (GTK_OBJECT (conbutton),
1402  "clicked",
1403  GTK_SIGNAL_FUNC (sendstr),
1404  GINT_TO_POINTER ("3"));
1405 
1406  intbutton = gtk_button_new_with_label ("Int");
1407  gtk_box_pack_start (GTK_BOX (hbox), intbutton, TRUE,
1408  TRUE, 1);
1409  gtk_signal_connect_object (GTK_OBJECT (intbutton),
1410  "clicked",
1411  GTK_SIGNAL_FUNC (sendstr),
1412  GINT_TO_POINTER ("4"));
1413 
1414  wisbutton = gtk_button_new_with_label ("Wis");
1415  gtk_box_pack_start (GTK_BOX (hbox), wisbutton, TRUE,
1416  TRUE, 1);
1417  gtk_signal_connect_object (GTK_OBJECT (wisbutton),
1418  "clicked",
1419  GTK_SIGNAL_FUNC (sendstr),
1420  GINT_TO_POINTER ("5"));
1421 
1422  powbutton = gtk_button_new_with_label ("Pow");
1423  gtk_box_pack_start (GTK_BOX (hbox), powbutton, TRUE,
1424  TRUE, 1);
1425  gtk_signal_connect_object (GTK_OBJECT (powbutton),
1426  "clicked",
1427  GTK_SIGNAL_FUNC (sendstr),
1428  GINT_TO_POINTER ("6"));
1429 
1430  chabutton = gtk_button_new_with_label ("Cha");
1431  gtk_box_pack_start (GTK_BOX (hbox), chabutton, TRUE,
1432  TRUE, 1);
1433  gtk_signal_connect_object (GTK_OBJECT (chabutton),
1434  "clicked",
1435  GTK_SIGNAL_FUNC (sendstr),
1436  GINT_TO_POINTER ("7"));
1437 
1438  gtk_widget_show (strbutton);
1439  gtk_widget_show (dexbutton);
1440  gtk_widget_show (conbutton);
1441  gtk_widget_show (intbutton);
1442  gtk_widget_show (wisbutton);
1443  gtk_widget_show (powbutton);
1444  gtk_widget_show (chabutton);
1445 
1446 
1447 
1448  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1449  6);
1450  gtk_widget_show (hbox);
1451 
1452  hbox = gtk_hbox_new (FALSE, 6);
1453 
1454  yesbutton = gtk_button_new_with_label ("Roll again");
1455  gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE,
1456  TRUE, 6);
1457  gtk_signal_connect_object (GTK_OBJECT (yesbutton),
1458  "clicked",
1459  GTK_SIGNAL_FUNC (sendstr),
1460  GINT_TO_POINTER ("y"));
1461 
1462  nobutton = gtk_button_new_with_label ("Keep this");
1463  gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE,
1464  TRUE, 6);
1465  gtk_signal_connect_object (GTK_OBJECT (nobutton),
1466  "clicked",
1467  GTK_SIGNAL_FUNC (sendstr),
1468  GINT_TO_POINTER ("n"));
1469 
1470  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1471  6);
1472 
1473  gtk_widget_show (yesbutton);
1474  gtk_widget_show (nobutton);
1475  gtk_widget_show (hbox);
1476 
1477  found = TRUE;
1478  continue;
1479  }
1480  if (!strncmp (last_str, "Str -", 5) ||
1481  !strncmp (last_str, "Dex -", 5)
1482  || !strncmp (last_str, "Con -", 5)
1483  || !strncmp (last_str, "Int -", 5)
1484  || !strncmp (last_str, "Wis -", 5)
1485  || !strncmp (last_str, "Pow -", 5)
1486  || !strncmp (last_str, "Cha -", 5))
1487  {
1488 
1489 
1490  dialoglabel =
1491  gtk_label_new ("Exchange with which ability?");
1492  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1493  TRUE, 6);
1494  gtk_widget_show (dialoglabel);
1495 
1496  hbox = gtk_hbox_new (TRUE, 2);
1497  strbutton = gtk_button_new_with_label ("Str");
1498  gtk_box_pack_start (GTK_BOX (hbox), strbutton, TRUE,
1499  TRUE, 1);
1500  gtk_signal_connect_object (GTK_OBJECT (strbutton),
1501  "clicked",
1502  GTK_SIGNAL_FUNC (sendstr),
1503  GINT_TO_POINTER ("1"));
1504 
1505 
1506  dexbutton = gtk_button_new_with_label ("Dex");
1507  gtk_box_pack_start (GTK_BOX (hbox), dexbutton, TRUE,
1508  TRUE, 1);
1509  gtk_signal_connect_object (GTK_OBJECT (dexbutton),
1510  "clicked",
1511  GTK_SIGNAL_FUNC (sendstr),
1512  GINT_TO_POINTER ("2"));
1513 
1514  conbutton = gtk_button_new_with_label ("Con");
1515  gtk_box_pack_start (GTK_BOX (hbox), conbutton, TRUE,
1516  TRUE, 1);
1517  gtk_signal_connect_object (GTK_OBJECT (conbutton),
1518  "clicked",
1519  GTK_SIGNAL_FUNC (sendstr),
1520  GINT_TO_POINTER ("3"));
1521 
1522  intbutton = gtk_button_new_with_label ("Int");
1523  gtk_box_pack_start (GTK_BOX (hbox), intbutton, TRUE,
1524  TRUE, 1);
1525  gtk_signal_connect_object (GTK_OBJECT (intbutton),
1526  "clicked",
1527  GTK_SIGNAL_FUNC (sendstr),
1528  GINT_TO_POINTER ("4"));
1529 
1530  wisbutton = gtk_button_new_with_label ("Wis");
1531  gtk_box_pack_start (GTK_BOX (hbox), wisbutton, TRUE,
1532  TRUE, 1);
1533  gtk_signal_connect_object (GTK_OBJECT (wisbutton),
1534  "clicked",
1535  GTK_SIGNAL_FUNC (sendstr),
1536  GINT_TO_POINTER ("5"));
1537 
1538  powbutton = gtk_button_new_with_label ("Pow");
1539  gtk_box_pack_start (GTK_BOX (hbox), powbutton, TRUE,
1540  TRUE, 1);
1541  gtk_signal_connect_object (GTK_OBJECT (powbutton),
1542  "clicked",
1543  GTK_SIGNAL_FUNC (sendstr),
1544  GINT_TO_POINTER ("6"));
1545 
1546  chabutton = gtk_button_new_with_label ("Cha");
1547  gtk_box_pack_start (GTK_BOX (hbox), chabutton, TRUE,
1548  TRUE, 1);
1549  gtk_signal_connect_object (GTK_OBJECT (chabutton),
1550  "clicked",
1551  GTK_SIGNAL_FUNC (sendstr),
1552  GINT_TO_POINTER ("7"));
1553 
1554  gtk_widget_show (strbutton);
1555  gtk_widget_show (dexbutton);
1556  gtk_widget_show (conbutton);
1557  gtk_widget_show (intbutton);
1558  gtk_widget_show (wisbutton);
1559  gtk_widget_show (powbutton);
1560  gtk_widget_show (chabutton);
1561 
1562 
1563  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1564  6);
1565  gtk_widget_show (hbox);
1566 
1567  found = TRUE;
1568  continue;
1569  }
1570 
1571  if (!strncmp (last_str, "Press `d'", 9))
1572  {
1573 
1574 
1575  dialoglabel = gtk_label_new ("Choose a character.");
1576  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1577  TRUE, 6);
1578  gtk_widget_show (dialoglabel);
1579 
1580  hbox = gtk_hbox_new (FALSE, 6);
1581 
1582  yesbutton = gtk_button_new_with_label ("Show next");
1583  gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE,
1584  TRUE, 6);
1585  gtk_signal_connect_object (GTK_OBJECT (yesbutton),
1586  "clicked",
1587  GTK_SIGNAL_FUNC (sendstr),
1588  GINT_TO_POINTER (" "));
1589 
1590  nobutton = gtk_button_new_with_label ("Keep this");
1591  gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE,
1592  TRUE, 6);
1593  gtk_signal_connect_object (GTK_OBJECT (nobutton),
1594  "clicked",
1595  GTK_SIGNAL_FUNC (sendstr),
1596  GINT_TO_POINTER ("d"));
1597 
1598  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1599  6);
1600 
1601  gtk_widget_show (yesbutton);
1602  gtk_widget_show (nobutton);
1603  gtk_widget_show (hbox);
1604 
1605  found = TRUE;
1606  continue;
1607  }
1608 
1609  if (!strncmp (str, "Do you want to play", 18))
1610  {
1611 
1612 
1613  dialoglabel =
1614  gtk_label_new ("Do you want to play again?");
1615  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1616  TRUE, 6);
1617  gtk_widget_show (dialoglabel);
1618 
1619  hbox = gtk_hbox_new (FALSE, 6);
1620 
1621  yesbutton = gtk_button_new_with_label ("Play again");
1622  gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE,
1623  TRUE, 6);
1624  gtk_signal_connect_object (GTK_OBJECT (yesbutton),
1625  "clicked",
1626  GTK_SIGNAL_FUNC (sendstr),
1627  GINT_TO_POINTER ("a"));
1628 
1629  nobutton = gtk_button_new_with_label ("Quit");
1630  gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE,
1631  TRUE, 6);
1632  gtk_signal_connect_object (GTK_OBJECT (nobutton),
1633  "clicked",
1634  GTK_SIGNAL_FUNC (sendstr),
1635  GINT_TO_POINTER ("q"));
1636 
1637  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1638  6);
1639 
1640  gtk_widget_show (yesbutton);
1641  gtk_widget_show (nobutton);
1642  gtk_widget_show (hbox);
1643 
1644  found = TRUE;
1645  continue;
1646  }
1647 
1648  if (!strncmp (str, "Are you sure you want", 21))
1649  {
1650 
1651 
1652  dialoglabel =
1653  gtk_label_new ("Are you sure you want to quit?");
1654  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1655  TRUE, 6);
1656  gtk_widget_show (dialoglabel);
1657 
1658  hbox = gtk_hbox_new (FALSE, 6);
1659 
1660  yesbutton = gtk_button_new_with_label ("Yes, quit");
1661  gtk_box_pack_start (GTK_BOX (hbox), yesbutton, TRUE,
1662  TRUE, 6);
1663  gtk_signal_connect_object (GTK_OBJECT (yesbutton),
1664  "clicked",
1665  GTK_SIGNAL_FUNC (sendstr),
1666  GINT_TO_POINTER ("y"));
1667 
1668  nobutton = gtk_button_new_with_label ("Don't quit");
1669  gtk_box_pack_start (GTK_BOX (hbox), nobutton, TRUE,
1670  TRUE, 6);
1671  gtk_signal_connect_object (GTK_OBJECT (nobutton),
1672  "clicked",
1673  GTK_SIGNAL_FUNC (sendstr),
1674  GINT_TO_POINTER ("n"));
1675 
1676  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1677  6);
1678 
1679  gtk_widget_show (yesbutton);
1680  gtk_widget_show (nobutton);
1681  gtk_widget_show (hbox);
1682 
1683  found = TRUE;
1684  continue;
1685  }
1686 
1687  if (!strcmp (last_str, "What is the password?"))
1688  {
1689 
1690  dialoglabel =
1691  gtk_label_new ("What is the party password?");
1692  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel,
1693  FALSE, TRUE, 6);
1694  gtk_widget_show (dialoglabel);
1695 
1696  hbox = gtk_hbox_new (FALSE, 6);
1697  dialogtext = gtk_entry_new ();
1698  gtk_entry_set_visibility (GTK_ENTRY (dialogtext),
1699  FALSE);
1700  gtk_signal_connect (GTK_OBJECT (dialogtext),
1701  "activate",
1702  GTK_SIGNAL_FUNC
1703  (dialog_callback),
1704  dialog_window);
1705  gtk_box_pack_start (GTK_BOX (hbox), dialogtext,
1706  TRUE, TRUE, 6);
1707  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE,
1708  TRUE, 6);
1709 
1710  gtk_widget_show (hbox);
1711 
1712  gtk_widget_show (dialogtext);
1713  gtk_widget_grab_focus (dialogtext);
1714  found = TRUE;
1715  continue;;
1716  }
1717 
1718  if (!found)
1719  {
1720  dialoglabel = gtk_label_new (str);
1721  gtk_box_pack_start (GTK_BOX (dbox), dialoglabel, FALSE,
1722  TRUE, 6);
1723  gtk_widget_show (dialoglabel);
1724 
1725  hbox = gtk_hbox_new (FALSE, 6);
1726  dialogtext = gtk_entry_new ();
1727  if (cpl.no_echo == 1)
1728  gtk_entry_set_visibility(GTK_ENTRY (dialogtext), FALSE);
1729 
1730  gtk_signal_connect (GTK_OBJECT (dialogtext), "activate",
1731  GTK_SIGNAL_FUNC (dialog_callback),
1732  dialog_window);
1733  gtk_box_pack_start (GTK_BOX (hbox), dialogtext, TRUE,
1734  TRUE, 6);
1735  gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, TRUE,
1736  6);
1737 
1738  gtk_widget_show (hbox);
1739  gtk_widget_show (dialogtext);
1740  gtk_widget_grab_focus (dialogtext);
1741  found = TRUE;
1742  continue;
1743  }
1744  }
1745 
1746  /* Finished with the contents. */
1747 
1748 
1749  gtk_widget_show (dbox);
1750  gtk_widget_show (dialog_window);
1751  }
1752 
1753 }
1754 
1755 /* draw_info adds a line to the info window. For speed reasons it will
1756  * automatically freeze the info window when adding text to it, set the
1757  * draw_info_freeze variable true and the actual drawing will take place
1758  * during the next do_timeout at which point it is unfrozen again. That way
1759  * we handle massive amounts of text addition with a single GUI event, which
1760  * results in a serious speed improvement for slow client machines (and
1761  * above all it avoids a GUI lockup when the client becomes congested with
1762  * updates (which is often when you're in the middle of fighting something
1763  * serious and not a good time to get slow reaction time)).
1764  *
1765  * MSW 2001-05-25: The removal of input from the text windows should
1766  * work, and in fact does about 90% of the time. But that 10% it
1767  * doesn't, the client crashes. The error itself is in the gtk library,
1768  * to hopefully they will fix it someday. The reason to do this is
1769  * to keep these buffers a reasonable size so that performance stays
1770  * good - otherwise, performance slowly degrades.
1771  */
1772 
1773 void draw_info(const char *str, int color) {
1774  int ncolor = color;
1775  char timestamp[11]="";
1776 
1777  if (ncolor==NDI_WHITE) {
1778  ncolor=NDI_BLACK;
1779  }
1780  if (use_config[CONFIG_TIMESTAMP] && color != NDI_BLACK) {
1781  struct tm *now;
1782  time_t currenttime = time(0);
1783  now = localtime(&currenttime);
1784  strftime(timestamp, 10, "%I:%M: ", now);
1785  }
1786  strcpy (last_str, str);
1787  if (use_config[CONFIG_SPLITINFO] && color != NDI_BLACK) {
1788  if (!draw_info_freeze2){
1789  gtk_text_freeze (GTK_TEXT (gtkwin_info_text2));
1791  }
1792  if (use_config[CONFIG_TRIMINFO]) {
1793  info2_num_chars += strlen(str) + 1;
1794  /* Limit size of scrollback buffer. To be more efficient, delete a good
1795  * blob (5000) characters at a time - in that way, there will be some
1796  * time between needing to delete.
1797  */
1799  gtk_text_set_point(GTK_TEXT(gtkwin_info_text2),0);
1800  gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text2), (info2_num_chars - info2_max_chars) + 5000);
1801  info2_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text2));
1802  gtk_text_set_point(GTK_TEXT(gtkwin_info_text2), info2_num_chars);
1803  LOG(LOG_INFO,"gtk::draw_info","reduced output buffer2 to %d chars", info1_num_chars);
1804  }
1805  }
1807  gtk_text_insert(GTK_TEXT (gtkwin_info_text2), NULL, &root_color[NDI_GREY], NULL, timestamp, -1);
1808  gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, str, -1);
1809  gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[ncolor], NULL, "\n" , -1);
1810 
1811  } else {
1812  /* All notes in the above section apply here also */
1813  if (!draw_info_freeze1){
1814  gtk_text_freeze (GTK_TEXT (gtkwin_info_text));
1816  }
1817  if (use_config[CONFIG_TRIMINFO]) {
1818  info1_num_chars += strlen(str) + 1;
1820 #if 1
1821  int to_delete = (info1_num_chars - info1_max_chars) + 5000;
1822  /* Delete on newline boundaries */
1823  while (GTK_TEXT_INDEX(GTK_TEXT(gtkwin_info_text), to_delete)!='\n')
1824  to_delete++;
1825  gtk_text_set_point(GTK_TEXT(gtkwin_info_text),0);
1826  gtk_text_forward_delete(GTK_TEXT(gtkwin_info_text), to_delete);
1827  info1_num_chars = gtk_text_get_length(GTK_TEXT(gtkwin_info_text));
1828  gtk_text_set_point(GTK_TEXT(gtkwin_info_text), info1_num_chars);
1829  LOG(LOG_INFO,"gtk::draw_info",
1830  "trim_info_window, deleted %d characters, %d remaining",
1831  to_delete, info1_num_chars);
1832 #else
1833  /* This works, so it is possible to completely clear the window */
1834  info1_num_chars = gtk_text_get_length(GTK_TEXT (gtkwin_info_text));
1835  gtk_text_set_point(GTK_TEXT (gtkwin_info_text), 0);
1836  gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text), info1_num_chars );
1837  gtk_text_thaw (GTK_TEXT (gtkwin_info_text));
1838  info1_num_chars=0;
1839 #endif
1840  }
1841 
1842  }
1844  gtk_text_insert (GTK_TEXT (gtkwin_info_text2), NULL, &root_color[NDI_GREY], NULL, timestamp, -1);
1845  gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, str , -1);
1846  gtk_text_insert (GTK_TEXT (gtkwin_info_text), NULL, &root_color[ncolor], NULL, "\n" , -1);
1847  }
1848 }
1849 
1850 
1851 void draw_color_info(int colr, const char *buf){
1852  draw_info(buf,colr);
1853 }
1854 
1855 /***********************************************************************
1856  *
1857  * Stats window functions follow
1858  *
1859  ***********************************************************************/
1860 
1861 static int get_stats_display(GtkWidget *frame) {
1862  GtkWidget *stats_vbox;
1863  GtkWidget *stats_box_1;
1864  GtkWidget *stats_box_2;
1865  GtkWidget *stats_box_4;
1866  GtkWidget *stats_box_5;
1867  GtkWidget *stats_box_6;
1868  GtkWidget *stats_box_7;
1869  GtkWidget *table;
1870  int i,x,y;
1871 
1872 
1873  stats_vbox = gtk_vbox_new (FALSE, 0);
1874 
1875  /* 1st row - Player name */
1876  stats_box_1 = gtk_hbox_new (FALSE, 0);
1877 
1878  statwindow.playername = gtk_label_new("Player: ");
1879  gtk_box_pack_start (GTK_BOX (stats_box_1), statwindow.playername, FALSE, FALSE, 5);
1880  gtk_widget_show (statwindow.playername);
1881 
1882  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_1, FALSE, FALSE, 0);
1883  gtk_widget_show (stats_box_1);
1884 
1885  /* 2nd row - score and level */
1886  stats_box_2 = gtk_hbox_new (FALSE, 0);
1887  statwindow.score = gtk_label_new("Score: 0");
1888  gtk_box_pack_start (GTK_BOX (stats_box_2), statwindow.score, FALSE, FALSE, 5);
1889  gtk_widget_show (statwindow.score);
1890 
1891  statwindow.level = gtk_label_new("Level: 0");
1892  gtk_box_pack_start (GTK_BOX (stats_box_2), statwindow.level, FALSE, FALSE, 5);
1893  gtk_widget_show (statwindow.level);
1894 
1895  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_2, FALSE, FALSE, 0);
1896  gtk_widget_show (stats_box_2);
1897 
1898 
1899  /* 4th row (really the thrid) - the stats - str, dex, con, etc */
1900  stats_box_4 = gtk_hbox_new (FALSE, 0);
1901 
1902  statwindow.Str = gtk_label_new("S 0");
1903  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Str, FALSE, FALSE, 5);
1904  gtk_widget_show (statwindow.Str);
1905 
1906  statwindow.Dex = gtk_label_new("D 0");
1907  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Dex, FALSE, FALSE, 5);
1908  gtk_widget_show (statwindow.Dex);
1909 
1910  statwindow.Con = gtk_label_new("Co 0");
1911  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Con, FALSE, FALSE, 5);
1912  gtk_widget_show (statwindow.Con);
1913 
1914  statwindow.Int = gtk_label_new("I 0");
1915  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Int, FALSE, FALSE, 5);
1916  gtk_widget_show (statwindow.Int);
1917 
1918  statwindow.Wis = gtk_label_new("W 0");
1919  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Wis, FALSE, FALSE, 5);
1920  gtk_widget_show (statwindow.Wis);
1921 
1922  statwindow.Pow = gtk_label_new("P 0");
1923  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Pow, FALSE, FALSE, 5);
1924  gtk_widget_show (statwindow.Pow);
1925 
1926  statwindow.Cha = gtk_label_new("Ch 0");
1927  gtk_box_pack_start (GTK_BOX (stats_box_4), statwindow.Cha, FALSE, FALSE, 5);
1928  gtk_widget_show (statwindow.Cha);
1929 
1930  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_4, FALSE, FALSE, 0);
1931  gtk_widget_show (stats_box_4);
1932 
1933  /* 5th row wc, dam, ac, armor*/
1934 
1935  stats_box_5 = gtk_hbox_new (FALSE, 0);
1936 
1937  statwindow.wc = gtk_label_new("Wc: 0");
1938  gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.wc, FALSE, FALSE, 5);
1939  gtk_widget_show (statwindow.wc);
1940 
1941  statwindow.dam = gtk_label_new("Dam: 0");
1942  gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.dam, FALSE, FALSE, 5);
1943  gtk_widget_show (statwindow.dam);
1944 
1945  statwindow.ac = gtk_label_new("Ac: 0");
1946  gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.ac, FALSE, FALSE, 5);
1947  gtk_widget_show (statwindow.ac);
1948 
1949  statwindow.armor = gtk_label_new("Armor: 0");
1950  gtk_box_pack_start (GTK_BOX (stats_box_5), statwindow.armor, FALSE, FALSE, 5);
1951  gtk_widget_show (statwindow.armor);
1952 
1953  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_5, FALSE, FALSE, 0);
1954  gtk_widget_show (stats_box_5);
1955 
1956  /* 6th row speed and weapon speed */
1957 
1958  stats_box_6 = gtk_hbox_new (FALSE, 0);
1959 
1960  statwindow.speed = gtk_label_new("Speed: 0");
1961  gtk_box_pack_start (GTK_BOX (stats_box_6), statwindow.speed, FALSE, FALSE, 5);
1962  gtk_widget_show (statwindow.speed);
1963 
1964  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_6, FALSE, FALSE, 0);
1965  gtk_widget_show (stats_box_6);
1966 
1967  /* 7th row - range */
1968 
1969  stats_box_7 = gtk_hbox_new (FALSE, 0);
1970 
1971  statwindow.skill = gtk_label_new("Skill: 0");
1972  gtk_box_pack_start (GTK_BOX (stats_box_7), statwindow.skill, FALSE, FALSE, 5);
1973  gtk_widget_show (statwindow.skill);
1974  gtk_box_pack_start (GTK_BOX (stats_vbox), stats_box_7, FALSE, FALSE, 0);
1975  gtk_widget_show (stats_box_7);
1976 
1977 
1978  /* Start of experience display - we do it in a 4 x 4 array. Use a table
1979  * so that spacing is uniform - this should look better.
1980  * Change it so we use one field for the name, and the other for exp -
1981  * in this way, the values line up better.
1982  */
1983 
1984  table = gtk_table_new (4, 4, FALSE);
1985  x=0;
1986  y=0;
1987  /* This is all the same - we just pack it in different places */
1988  for (i=0; i<MAX_SKILL*2; i++) {
1989  statwindow.skill_exp[i] = gtk_label_new("");
1990  gtk_table_attach(GTK_TABLE(table), statwindow.skill_exp[i], x, x+1, y, y+1, GTK_FILL | GTK_EXPAND, 0, 10, 0);
1991  x++;
1992  if (x==4) { x=0; y++; }
1993  gtk_widget_show(statwindow.skill_exp[i]);
1994  }
1995  skill_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1996  gtk_container_set_border_width (GTK_CONTAINER (res_scrolled_window), 0);
1997  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (skill_scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1998  gtk_box_pack_start(GTK_BOX(stats_vbox), skill_scrolled_window, TRUE, TRUE, 0);
1999  gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (skill_scrolled_window), table);
2000 
2001  gtk_widget_show(table);
2002 
2003  gtk_container_add (GTK_CONTAINER (frame), stats_vbox);
2004  gtk_widget_show (stats_vbox);
2005  gtk_widget_show (skill_scrolled_window);
2006 
2007  return 0;
2008 }
2009 
2010 /* This draws the stats window. If redraw is true, it means
2011  * we need to redraw the entire thing, and not just do an
2012  * updated.
2013  */
2014 
2015 void draw_stats(int redraw) {
2016  static Stats last_stats;
2017  static char last_name[MAX_BUF]="", last_range[MAX_BUF]="";
2018  static int init_before=0, lastbeep=0, max_drawn_skill=0;
2019 
2020  float weap_sp;
2021  char buff[MAX_BUF];
2022  int i, on_skill;
2023 
2024  if (!init_before) {
2025  init_before=1;
2026  memset(&last_stats, 0, sizeof(Stats));
2027  }
2028 
2029  if (updatelock < 25) {
2030  updatelock++;
2031  if (strcmp(cpl.title, last_name) || redraw) {
2032  strcpy(last_name,cpl.title);
2033  strcpy(buff,cpl.title);
2034  gtk_label_set (GTK_LABEL(statwindow.playername), cpl.title);
2035  gtk_widget_draw (statwindow.playername, NULL);
2036  }
2037 
2038  if(redraw || cpl.stats.exp!=last_stats.exp) {
2039  last_stats.exp = cpl.stats.exp;
2040  sprintf(buff,"Score: %5" FMT64 ,cpl.stats.exp);
2041 
2042  gtk_label_set (GTK_LABEL(statwindow.score), buff);
2043  gtk_widget_draw (statwindow.score, NULL);
2044  }
2045 
2046  if(redraw || cpl.stats.level!=last_stats.level) {
2047  last_stats.level = cpl.stats.level;
2048  sprintf(buff,"Level: %d",cpl.stats.level);
2049  gtk_label_set (GTK_LABEL(statwindow.level), buff);
2050  gtk_widget_draw (statwindow.level, NULL);
2051  }
2052 
2053  if(redraw ||
2054  cpl.stats.hp!=last_stats.hp || cpl.stats.maxhp!=last_stats.maxhp) {
2055  last_stats.hp=cpl.stats.hp;
2056  last_stats.maxhp=cpl.stats.maxhp;
2057  sprintf(buff,"Hp: %d/%d",cpl.stats.hp, cpl.stats.maxhp);
2058  gtk_label_set (GTK_LABEL(statwindow.hp), buff);
2059  gtk_widget_draw (statwindow.hp, NULL);
2060  }
2061 
2062  if(redraw ||
2063  cpl.stats.sp!=last_stats.sp || cpl.stats.maxsp!=last_stats.maxsp) {
2064  last_stats.sp=cpl.stats.sp;
2065  last_stats.maxsp=cpl.stats.maxsp;
2066  sprintf(buff,"Sp: %d/%d",cpl.stats.sp, cpl.stats.maxsp);
2067  gtk_label_set (GTK_LABEL(statwindow.sp), buff);
2068  gtk_widget_draw (statwindow.sp, NULL);
2069  }
2070 
2071  if(redraw ||
2072  cpl.stats.grace!=last_stats.grace || cpl.stats.maxgrace!=last_stats.maxgrace) {
2073  last_stats.grace=cpl.stats.grace;
2074  last_stats.maxgrace=cpl.stats.maxgrace;
2075  sprintf(buff,"Gr: %d/%d",cpl.stats.grace, cpl.stats.maxgrace);
2076  gtk_label_set (GTK_LABEL(statwindow.gr), buff);
2077  gtk_widget_draw (statwindow.gr, NULL);
2078  }
2079 
2080  if(redraw || cpl.stats.Str!=last_stats.Str) {
2081  last_stats.Str=cpl.stats.Str;
2082  sprintf(buff,"S%2d",cpl.stats.Str);
2083  gtk_label_set (GTK_LABEL(statwindow.Str), buff);
2084  gtk_widget_draw (statwindow.Str, NULL);
2085  }
2086 
2087  if(redraw || cpl.stats.Dex!=last_stats.Dex) {
2088  last_stats.Dex=cpl.stats.Dex;
2089  sprintf(buff,"D%2d",cpl.stats.Dex);
2090  gtk_label_set (GTK_LABEL(statwindow.Dex), buff);
2091  gtk_widget_draw (statwindow.Dex, NULL);
2092  }
2093 
2094  if(redraw || cpl.stats.Con!=last_stats.Con) {
2095  last_stats.Con=cpl.stats.Con;
2096  sprintf(buff,"Co%2d",cpl.stats.Con);
2097  gtk_label_set (GTK_LABEL(statwindow.Con), buff);
2098  gtk_widget_draw (statwindow.Con, NULL);
2099  }
2100 
2101  if(redraw || cpl.stats.Int!=last_stats.Int) {
2102  last_stats.Int=cpl.stats.Int;
2103  sprintf(buff,"I%2d",cpl.stats.Int);
2104  gtk_label_set (GTK_LABEL(statwindow.Int), buff);
2105  gtk_widget_draw (statwindow.Int, NULL);
2106  }
2107 
2108  if(redraw || cpl.stats.Wis!=last_stats.Wis) {
2109  last_stats.Wis=cpl.stats.Wis;
2110  sprintf(buff,"W%2d",cpl.stats.Wis);
2111  gtk_label_set (GTK_LABEL(statwindow.Wis), buff);
2112  gtk_widget_draw (statwindow.Wis, NULL);
2113  }
2114 
2115  if(redraw || cpl.stats.Pow!=last_stats.Pow) {
2116  last_stats.Pow=cpl.stats.Pow;
2117  sprintf(buff,"P%2d",cpl.stats.Pow);
2118  gtk_label_set (GTK_LABEL(statwindow.Pow), buff);
2119  gtk_widget_draw (statwindow.Pow, NULL);
2120  }
2121 
2122  if(redraw || cpl.stats.Cha!=last_stats.Cha) {
2123  last_stats.Cha=cpl.stats.Cha;
2124  sprintf(buff,"Ch%2d",cpl.stats.Cha);
2125  gtk_label_set (GTK_LABEL(statwindow.Cha), buff);
2126  gtk_widget_draw (statwindow.Cha, NULL);
2127  }
2128 
2129  if(redraw || cpl.stats.wc!=last_stats.wc) {
2130  last_stats.wc=cpl.stats.wc;
2131  sprintf(buff,"Wc%3d",cpl.stats.wc);
2132  gtk_label_set (GTK_LABEL(statwindow.wc), buff);
2133  gtk_widget_draw (statwindow.wc, NULL);
2134  }
2135 
2136  if(redraw || cpl.stats.dam!=last_stats.dam) {
2137  last_stats.dam=cpl.stats.dam;
2138  sprintf(buff,"Dam%3d",cpl.stats.dam);
2139  gtk_label_set (GTK_LABEL(statwindow.dam), buff);
2140  gtk_widget_draw (statwindow.dam, NULL);
2141  }
2142 
2143  if(redraw || cpl.stats.ac!=last_stats.ac) {
2144  last_stats.ac=cpl.stats.ac;
2145  sprintf(buff,"Ac%3d",cpl.stats.ac);
2146  gtk_label_set (GTK_LABEL(statwindow.ac), buff);
2147  gtk_widget_draw (statwindow.ac, NULL);
2148  }
2149 
2150  if(redraw || cpl.stats.resists[0]!=last_stats.resists[0]) {
2151  last_stats.resists[0]=cpl.stats.resists[0];
2152  sprintf(buff,"Arm%3d",cpl.stats.resists[0]);
2153  gtk_label_set (GTK_LABEL(statwindow.armor), buff);
2154  gtk_widget_draw (statwindow.armor, NULL);
2155  }
2156 
2157  if(redraw || cpl.stats.speed!=last_stats.speed ||
2158  cpl.stats.weapon_sp != last_stats.weapon_sp) {
2159  last_stats.speed=cpl.stats.speed;
2160  last_stats.weapon_sp=cpl.stats.weapon_sp;
2161  weap_sp = (float) cpl.stats.speed/((float)cpl.stats.weapon_sp);
2162  sprintf(buff,"Speed: %3.2f (%1.2f)",(float)cpl.stats.speed/FLOAT_MULTF,weap_sp);
2163  gtk_label_set (GTK_LABEL(statwindow.speed), buff);
2164  gtk_widget_draw (statwindow.speed, NULL);
2165  }
2166 
2167  if(redraw || cpl.stats.food!=last_stats.food) {
2168  last_stats.food=cpl.stats.food;
2169  sprintf(buff,"Food: %3d",cpl.stats.food);
2170  gtk_label_set (GTK_LABEL(statwindow.food), buff);
2171  gtk_widget_draw (statwindow.food, NULL);
2172  if (use_config[CONFIG_FOODBEEP] && (cpl.stats.food%4==3) && (cpl.stats.food < 200))
2173 #ifndef WIN32
2174  XBell(GDK_DISPLAY(), 0);
2175 #else
2176  gdk_beep( );
2177 #endif
2178  } else if (use_config[CONFIG_FOODBEEP] && cpl.stats.food == 0 && ++lastbeep == 5) {
2179  lastbeep = 0;
2180 #ifndef WIN32
2181  XBell(GDK_DISPLAY(), 0);
2182 #else
2183  gdk_beep( );
2184 #endif
2185  }
2186 
2187  if(redraw || strcmp(cpl.range, last_range)) {
2188  strcpy(last_range, cpl.range);
2189  gtk_label_set (GTK_LABEL(statwindow.skill), cpl.range);
2190  gtk_widget_draw (statwindow.skill, NULL);
2191  }
2192  on_skill=0;
2193  for (i=0; i<MAX_SKILL; i++) {
2194  /* Drawing a particular skill entry is tricky - only draw if
2195  * different, and only draw if we have a name for the skill
2196  * and the player has some exp in the skill - don't draw
2197  * all 30 skills for no reason.
2198  */
2199  if ((redraw || cpl.stats.skill_exp[i] != last_stats.skill_exp[i]) &&
2200  skill_names[i] && cpl.stats.skill_level[i]) {
2201  gtk_label_set(GTK_LABEL(statwindow.skill_exp[on_skill++]), skill_names[i]);
2202  sprintf(buff,"%" FMT64 " (%d)", cpl.stats.skill_exp[i], cpl.stats.skill_level[i]);
2203  gtk_label_set(GTK_LABEL(statwindow.skill_exp[on_skill++]), buff);
2204  last_stats.skill_level[i] = cpl.stats.skill_level[i];
2205  last_stats.skill_exp[i] = cpl.stats.skill_exp[i];
2206  } else if (cpl.stats.skill_level[i]) {
2207  /* Don't need to draw the skill, but need to update the position
2208  * of where to draw the next one.
2209  */
2210  on_skill+=2;
2211  }
2212  }
2213  /* Since the number of skills we draw come and go, basically we want
2214  * to erase any extra. This shows up when switching characters, eg, character
2215  * #1 knows 10 skills, #2 knows 5 - need to erase those 5 extra.
2216  */
2217  if (on_skill < max_drawn_skill) {
2218  int k;
2219 
2220  for (k = on_skill; k <= max_drawn_skill; k++)
2221  gtk_label_set(GTK_LABEL(statwindow.skill_exp[k]), "");
2222  }
2223  max_drawn_skill = on_skill;
2224  } /* updatelock < 25 */
2225 }
2226 
2227 
2228 /***********************************************************************
2229 *
2230 * Handles the message window
2231 *
2232 ***********************************************************************/
2233 
2234 
2235 static void create_stat_bar(GtkWidget *mtable, gint row, const gchar *label, gint bar, GtkWidget **plabel) {
2236  /* GtkWidget *plabel;*/
2237 
2238  *plabel = gtk_label_new (label);
2239  gtk_table_attach (GTK_TABLE (mtable), *plabel, 0, 1, row, row+1,/*GTK_FILL |*/ GTK_EXPAND,GTK_FILL | GTK_EXPAND,0,0);
2240  gtk_widget_show (*plabel);
2241 
2242  vitals[bar].bar = gtk_progress_bar_new ();
2243  gtk_table_attach(GTK_TABLE(mtable), vitals[bar].bar, 0,1,row+1,row+2,GTK_FILL | GTK_EXPAND, 0 ,3,0);
2244  gtk_widget_set_usize (vitals[bar].bar,100,15);
2245 
2246 
2247  gtk_widget_show (vitals[bar].bar);
2248 
2249 
2250 
2251  vitals[bar].state=1;
2252 
2253  vitals[bar].style[0] = gtk_style_new ();
2254  vitals[bar].style[0]->bg[GTK_STATE_PRELIGHT] = gdk_green;
2255  gtk_widget_set_style (vitals[bar].bar, vitals[bar].style[0]);
2256  vitals[bar].style[1] = gtk_style_new ();
2257  vitals[bar].style[1]->bg[GTK_STATE_PRELIGHT] = gdk_red;
2258 
2259 }
2260 
2261 /* This is used when going from gradiated color stat bars back
2262  * to the normal - we need to reset the colors.
2263  */
2264 void reset_stat_bars(void) {
2265  int i;
2266 
2267  for (i=0; i<4; i++) {
2268  vitals[i].style[0]->bg[GTK_STATE_PRELIGHT] = gdk_green;
2269  vitals[i].style[1]->bg[GTK_STATE_PRELIGHT] = gdk_red;
2270  /* Need to do this double switch so that the color gets updated. Otherwise,
2271  * if we are currently using style[0] to draw, the update above won't
2272  * have any effect.
2273  */
2274  gtk_widget_set_style(vitals[i].bar, vitals[i].style[1]);
2275  gtk_widget_set_style(vitals[i].bar, vitals[i].style[0]);
2276  vitals[i].state = 0;
2277 
2278  }
2280 }
2281 
2282 static int get_message_display(GtkWidget *frame) {
2283  GtkWidget *mtable;
2284  GtkWidget *vbox;
2285  GtkWidget *res_mainbox;
2286  GtkWidget *reswindow;
2287 
2288  /* Initialize the main hbox */
2289  res_mainbox = gtk_hbox_new (TRUE,0);
2290  gtk_container_add (GTK_CONTAINER(frame), res_mainbox);
2291 
2292  /* stat bar part - start */
2293 
2294  /* Initialize the vbox for the stat bars (Hp,Mana,Grace,Food)
2295  * and pack it into the main hbox
2296  */
2297  vbox = gtk_vbox_new (FALSE, 0);
2298  gtk_box_pack_start (GTK_BOX(res_mainbox), vbox, FALSE, TRUE, 0);
2299 
2300  /* Initialize the table and pack this into the vbox */
2301  mtable = gtk_table_new (2,4,FALSE);
2302  gtk_box_pack_start (GTK_BOX(vbox),mtable,FALSE,FALSE,0);
2303 
2304  /* Create the stat bars and place them in the table */
2305  create_stat_bar (mtable, 1,"Hp: 0",0, &statwindow.hp);
2306  create_stat_bar (mtable, 3,"Mana: 0",1, &statwindow.sp);
2307  create_stat_bar (mtable, 5,"Grace: 0",2, &statwindow.gr);
2308  create_stat_bar (mtable, 7,"Food: 0",3, &statwindow.food);
2309 
2310  /* Stat bar part - end */
2311 
2312 
2313  /* Resistances table part - start */
2314 
2315  /* Initialize the hbox for the resistances table */
2316  reswindow = gtk_hbox_new (TRUE, 0);
2317  gtk_box_pack_start(GTK_BOX(res_mainbox), reswindow, FALSE, TRUE, 0);
2318 
2319  /* Create the resistance table*/
2320  restable = gtk_table_new (4,12,FALSE);
2321 
2322  /* Packing the restable in a scrollable window*/
2323  res_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
2324  gtk_container_set_border_width (GTK_CONTAINER (res_scrolled_window), 0);
2325  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (res_scrolled_window),
2326  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2327  gtk_box_pack_start(GTK_BOX(reswindow), res_scrolled_window, TRUE, TRUE, 0);
2328  gtk_widget_show (res_scrolled_window);
2329  gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW (res_scrolled_window), restable);
2330 
2331  /* Finally, draw the resistances table */
2333 
2334  /* Resistances table part - end */
2335 
2336  /* Now showing all not already showed widgets */
2337  gtk_widget_show (res_mainbox);
2338  gtk_widget_show (reswindow);
2339  gtk_widget_show (restable);
2340  gtk_widget_show (mtable);
2341  gtk_widget_show (vbox);
2342  return 0;
2343 }
2344 
2345 /* This handles layout of the resistance window.
2346  * We end up just removing (and thus freeing) all the data and
2347  * then create new entries. This keeps things simpler, because
2348  * in basic mode, not all the resist[] widgets are attached,
2349  */
2350 void resize_resistance_table(int resists_show) {
2351  int i, left=0, right=0;
2352 
2353  while (GTK_TABLE(restable)->children) {
2354  GtkTableChild *child;
2355  child = GTK_TABLE(restable)->children->data;
2356 
2357  gtk_container_remove(GTK_CONTAINER(restable),
2358  child->widget);
2359  }
2360 
2361  /* Initialize labels for all modes of CONFIG_RESISTS */
2362  fire_label = gtk_label_new (" ");
2363  run_label = gtk_label_new (" ");
2364 
2365  /* Place labels for dual-column mode of CONFIG_RESISTS */
2366  if (resists_show) {
2367  gtk_table_resize(GTK_TABLE(restable), 4,12);
2368  gtk_table_attach (GTK_TABLE(restable), fire_label, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2369  gtk_table_attach (GTK_TABLE(restable), run_label, 3, 4, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2370  }
2371  else { /* Single column mode */
2372  gtk_table_resize(GTK_TABLE(restable), 2,24);
2373  gtk_table_attach (GTK_TABLE(restable), fire_label, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2374  gtk_table_attach (GTK_TABLE(restable), run_label, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2375  }
2376  /* Show labels for all modes of CONFIG_RESISTS */
2377  gtk_widget_show (fire_label);
2378  gtk_widget_show (run_label);
2379  /* Make and place labels for showing the resistances - start */
2380 
2381  for (i=0; i< NUM_RESISTS; i++) {
2382  resists[i] = gtk_label_new(" ");
2383 
2384  /* Place the labels for dual columns in the table restable */
2385  if (resists_show) {
2386  if ((i/2)*2 != i) {
2387  left++;
2388  gtk_table_attach (GTK_TABLE(restable), resists[i], 1, 2, 3+left, 4+left, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2389  } else {
2390  right++;
2391  gtk_table_attach (GTK_TABLE(restable), resists[i], 3, 4, 3+right, 4+right, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2392  }
2393  gtk_widget_show (resists[i]);
2394  }
2395  else { /* Single column style */
2396  gtk_table_attach (GTK_TABLE(restable), resists[i], 0, 2, 3+i, 4+i, GTK_FILL | GTK_EXPAND, 0, 0, 0);
2397  gtk_widget_show (resists[i]);
2398  }
2399  }
2400  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (res_scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2401 }
2402 
2403 static void draw_stat_bar(int bar_pos, float bar, int is_alert)
2404 {
2406  /* In this mode, the color of the stat bar were go between red and green
2407  * in a gradual style. This, at 50% of the value, the stat bar will be
2408  * drawn in yellow. Pure fluff I know.
2409  */
2410  int nstyle;
2411  GdkColor ncolor;
2412  /* We need to figure out what style to use. We can't call gtk_widget_set_style
2413  * on the widget currently in use - doing so results in no effect.
2414  * 53247 is float value of 0xcfff, which is the value used in the gdk_red
2415  * and gdk_green values. We double the values, so that it scales properly -
2416  * at .5, it then matches 53247, so the scaling appears proper.
2417  */
2418  if (gtk_widget_get_style(vitals[bar_pos].bar) == vitals[bar_pos].style[0]) nstyle=1;
2419  else nstyle=0;
2420  /* We are 'supercharged' - scale to max of 2.0 for pure blue */
2421  if (bar > 1.0) {
2422  if (bar>2.0) bar=2.0; /* Doesn't affect display, just are calculations */
2423  ncolor.blue = 65535.0 * (bar - 1.0);
2424  ncolor.green = 53247.0 * (2.0 - bar);
2425  ncolor.red = 0;
2426  bar=1.0;
2427  } else {
2428  /* Use 0.5 as the adjustment - basically, if greater than 0.5,
2429  * we have pure green with lesser amounts of red. If less than
2430  * 0.5, we have pure red with lesser amounts of green.
2431  */
2432  if (bar < 0.0) bar=0.0; /* Like above, doesn't affect display */
2433  if (bar >= 0.5) ncolor.green = 0xcfff;
2434  else ncolor.green = 106494.0 * bar;
2435  if (bar <= 0.5) ncolor.red = 0xcfff;
2436  else ncolor.red = 106494.0 * (1.0 - bar);
2437  ncolor.blue = 0;
2438  }
2439  vitals[bar_pos].style[nstyle]->bg[GTK_STATE_PRELIGHT] = ncolor;
2440  gtk_widget_set_style(vitals[bar_pos].bar, vitals[bar_pos].style[nstyle]);
2441  vitals[bar_pos].state=is_alert;
2442  } else {
2443  if (bar>1.0) bar=1.0;
2444  if (is_alert) is_alert=1; /* Safety check */
2445  if (vitals[bar_pos].state!=is_alert) {
2446  gtk_widget_set_style (vitals[bar_pos].bar, vitals[bar_pos].style[is_alert]);
2447  vitals[bar_pos].state=is_alert;
2448  }
2449  }
2450  gtk_progress_bar_update (GTK_PROGRESS_BAR (vitals[bar_pos].bar),bar );
2451  gtk_widget_draw (vitals[bar_pos].bar, NULL);
2452 }
2453 
2454 /* This updates the status bars. If redraw, then redraw them
2455  * even if they have not changed
2456  */
2457 
2458 void draw_message_window(int redraw) {
2459  float bar;
2460  int is_alert,flags;
2461  static uint16 scrollsize_hp=0, scrollsize_sp=0, scrollsize_food=0,
2462  scrollsize_grace=0;
2463  static uint8 scrollhp_alert=FALSE, scrollsp_alert=FALSE,
2464  scrollfood_alert=FALSE, scrollgrace_alert=FALSE;
2465 
2466  if (updatelock < 25) {
2467  updatelock++;
2468  /* Draw hp bar */
2469  if(cpl.stats.maxhp>0)
2470  {
2471  bar=(float)cpl.stats.hp/cpl.stats.maxhp;
2472  if(bar<=0)
2473  bar=(float)0.01;
2474  is_alert=(cpl.stats.hp <= cpl.stats.maxhp/4);
2475  }
2476  else
2477  {
2478  bar=(float)0.01;
2479  is_alert=0;
2480  }
2481 
2482  if (redraw || scrollsize_hp!=bar || scrollhp_alert!=is_alert)
2483  draw_stat_bar(0, bar, is_alert);
2484 
2485  scrollsize_hp=bar;
2486  scrollhp_alert=is_alert;
2487 
2488  /* Draw sp bar. Let draw_stats_bar handle high values */
2489  bar=(float)cpl.stats.sp/cpl.stats.maxsp;
2490  if(bar<=0)
2491  bar=(float)0.01;
2492 
2493  is_alert=(cpl.stats.sp <= cpl.stats.maxsp/4);
2494 
2495  if (redraw || scrollsize_sp!=bar || scrollsp_alert!=is_alert)
2496  draw_stat_bar(1, bar, is_alert);
2497 
2498  scrollsize_sp=bar;
2499  scrollsp_alert=is_alert;
2500 
2501  /* Draw grace bar. Grace can go above max or below min */
2502  bar=(float)cpl.stats.grace/cpl.stats.maxgrace;
2503  if(bar<=0)
2504  bar=(float)0.01;
2505 
2506  is_alert=(cpl.stats.grace <= cpl.stats.maxgrace/4);
2507 
2508  if (redraw || scrollsize_grace!=bar || scrollgrace_alert!=is_alert)
2509  draw_stat_bar(2, bar, is_alert);
2510 
2511  scrollsize_grace=bar;
2512  scrollgrace_alert=is_alert;
2513 
2514  /* Draw food bar */
2515  bar=(float)cpl.stats.food/999;
2516  if(bar<=0)
2517  bar=(float)0.01;
2518  is_alert=(cpl.stats.food <= 999/4);
2519 
2520  if (redraw || scrollsize_food!=bar || scrollfood_alert!=is_alert)
2521  draw_stat_bar(3, bar, is_alert);
2522 
2523  scrollsize_food=bar;
2524  scrollfood_alert=is_alert;
2525 
2526  flags = cpl.stats.flags;
2527 
2528  if (redraw || cpl.stats.resist_change) {
2529  int i,j=0;
2530  char buf[40];
2531 
2533  for (i=0; i<NUM_RESISTS; i++) {
2534  if (cpl.stats.resists[i]) {
2535  sprintf(buf,"%-10s %+4d",
2536  resists_name[i], cpl.stats.resists[i]);
2537  gtk_label_set(GTK_LABEL(resists[j]), buf);
2538  gtk_widget_draw(resists[j], NULL);
2539  j++;
2540  if (j >= NUM_RESISTS) break;
2541  }
2542  }
2543  /* Erase old/unused resistances */
2544  while (j<NUM_RESISTS) {
2545  gtk_label_set(GTK_LABEL(resists[j]), " ");
2546  gtk_widget_draw(resists[j], NULL);
2547  j++;
2548  }
2549  } /* if we draw the resists */
2550  }
2551  else {
2552  /* printf ("WARNING -- RACE. Frozen updates until updatelock is cleared!\n");*/
2553  }
2554 }
2555 
2556 
2557 
2558 
2559 
2560 
2561 
2562 /****************************************************************************
2563  *
2564  * Dialogue boxes and the menus that raise them.
2565  *
2566  ****************************************************************************/
2567 
2568 static void aboutdialog(GtkWidget *widget) {
2569 #include "help/about.h"
2570  GtkWidget *vbox;
2571  GtkWidget *hbox;
2572  GtkWidget *aboutlabel;
2573  GtkWidget *vscrollbar;
2574  GtkWidget *aboutbutton;
2575  GtkWidget *aboutgtkpixmap;
2576  GdkPixmap *aboutgdkpixmap;
2577  GdkBitmap *aboutgdkmask;
2578 
2579  GtkStyle *style;
2580 
2581  if(!gtkwin_about) {
2582 
2583  gtkwin_about = gtk_window_new (GTK_WINDOW_DIALOG);
2584  gtk_window_position (GTK_WINDOW (gtkwin_about), GTK_WIN_POS_CENTER);
2585  gtk_widget_set_usize (gtkwin_about,500,210);
2586  gtk_window_set_title (GTK_WINDOW (gtkwin_about), "About Crossfire");
2587 
2588  gtk_signal_connect (GTK_OBJECT (gtkwin_about), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_about);
2589 
2590  gtk_container_border_width (GTK_CONTAINER (gtkwin_about), 0);
2591  vbox = gtk_vbox_new(FALSE, 2);
2592  gtk_container_add (GTK_CONTAINER(gtkwin_about),vbox);
2593  style = gtk_widget_get_style(gtkwin_about);
2594  gtk_widget_realize(gtkwin_about);
2595  aboutgdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_about->window,
2596  &aboutgdkmask,
2597  &style->bg[GTK_STATE_NORMAL],
2598  (gchar **)crossfiretitle_xpm);
2599  aboutgtkpixmap= gtk_pixmap_new (aboutgdkpixmap, aboutgdkmask);
2600  gtk_box_pack_start (GTK_BOX (vbox),aboutgtkpixmap, FALSE, TRUE, 0);
2601  gtk_widget_show (aboutgtkpixmap);
2602 
2603  hbox = gtk_hbox_new(FALSE, 2);
2604  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2605 
2606  aboutlabel = gtk_text_new (NULL, NULL);
2607  gtk_text_set_editable (GTK_TEXT (aboutlabel), FALSE);
2608  gtk_box_pack_start (GTK_BOX (hbox),aboutlabel, TRUE, TRUE, 0);
2609  gtk_widget_show (aboutlabel);
2610 
2611  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (aboutlabel)->vadj);
2612  gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0);
2613 
2614  gtk_widget_show (vscrollbar);
2615 
2616  gtk_widget_show (hbox);
2617 
2618  hbox = gtk_hbox_new(FALSE, 2);
2619 
2620  aboutbutton = gtk_button_new_with_label ("Close");
2621  gtk_signal_connect_object (GTK_OBJECT (aboutbutton), "clicked",
2622  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2623  GTK_OBJECT (gtkwin_about));
2624  gtk_box_pack_start (GTK_BOX (hbox), aboutbutton, TRUE, FALSE, 0);
2625  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2626  gtk_widget_show (aboutbutton);
2627  gtk_widget_show (hbox);
2628 
2629  gtk_widget_show (vbox);
2630  gtk_widget_show (gtkwin_about);
2631  gtk_text_insert (GTK_TEXT (aboutlabel), NULL, &aboutlabel->style->black,
2632  NULL, VERSION_INFO , -1);
2633  gtk_text_insert (GTK_TEXT (aboutlabel), NULL, &aboutlabel->style->black,
2634  NULL, text , -1);
2635  gtk_adjustment_set_value(GTK_TEXT(aboutlabel)->vadj, 0.0);
2636  }
2637  else {
2638  gdk_window_raise (gtkwin_about->window);
2639  }
2640 }
2641 
2642 static void createBugTracker(void) {
2643  if (bugtrack ==NULL){
2644  LogEntry* le;
2645  bugtrack = gtk_text_new (NULL, NULL);
2646  gtk_signal_connect (GTK_OBJECT (bugtrack), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &bugtrack);
2647  gtk_text_set_editable (GTK_TEXT (bugtrack), FALSE);
2648  gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, "MESSAGES TRACK:\n" , -1);
2649  for (le=LogFirst;le;le=le->next)
2650  gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, getLogText(le) , -1);
2651 
2652  }
2653 }
2654 
2655 static void bugdialog(GtkWidget *widget) {
2656 #include "help/bugreport.h"
2657  GtkWidget *vbox;
2658  GtkWidget *hbox;
2659  GtkWidget *buglabel;
2660  GtkWidget *vscrollbar;
2661  GtkWidget *bugbutton;
2662  GtkWidget *buggtkpixmap;
2663  GdkPixmap *buggdkpixmap;
2664  GdkBitmap *buggdkmask;
2665 
2666  GtkStyle *style;
2667 #ifndef CFGTK2
2668  GdkFont* font;
2669 #endif
2670 
2671  if(!gtkwin_bug) {
2672 
2673  gtkwin_bug = gtk_window_new (GTK_WINDOW_DIALOG);
2674  gtk_window_position (GTK_WINDOW (gtkwin_bug), GTK_WIN_POS_CENTER);
2675  gtk_widget_set_usize (gtkwin_bug,500,450);
2676  gtk_window_set_title (GTK_WINDOW (gtkwin_bug), "Report a bug in Crossfire");
2677 
2678  gtk_signal_connect (GTK_OBJECT (gtkwin_bug), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_bug);
2679  /*gtk_signal_connect (GTK_OBJECT (gtkwin_bug), "destroy", GTK_SIGNAL_FUNC(bugreportdestroy), &gtkwin_bug);*/
2680 
2681  gtk_container_border_width (GTK_CONTAINER (gtkwin_bug), 0);
2682  vbox = gtk_vbox_new(FALSE, 2);
2683  gtk_container_add (GTK_CONTAINER(gtkwin_bug),vbox);
2684  style = gtk_widget_get_style(gtkwin_bug);
2685  gtk_widget_realize(gtkwin_bug);
2686  buggdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_bug->window,
2687  &buggdkmask,
2688  &style->bg[GTK_STATE_NORMAL],
2689  (gchar **)crossfiretitle_xpm);
2690  buggtkpixmap= gtk_pixmap_new (buggdkpixmap, buggdkmask);
2691  gtk_box_pack_start (GTK_BOX (vbox),buggtkpixmap, FALSE, TRUE, 0);
2692  gtk_widget_show (buggtkpixmap);
2693 
2694  hbox = gtk_hbox_new(FALSE, 2);
2695  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2696 
2697  buglabel = gtk_text_new (NULL, NULL);
2698  gtk_widget_set_style(buglabel,style);
2699  /*GtkStyle* gtk_widget_get_style (GtkWidget *widget);*/
2700  gtk_text_set_editable (GTK_TEXT (buglabel), FALSE);
2701  gtk_box_pack_start (GTK_BOX (hbox),buglabel, TRUE, TRUE, 0);
2702  gtk_widget_show (buglabel);
2703 
2704  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (buglabel)->vadj);
2705  gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0);
2706 
2707  gtk_widget_show (vscrollbar);
2708 
2709  gtk_widget_show (hbox);
2710  hbox = gtk_hbox_new(FALSE, 2);
2711  createBugTracker();
2712 #ifndef CFGTK2
2713  /* Win32 uses GTK2, this apparently doesn't work... */
2714  font = gdk_font_load ("-*-fixed-*-*-*-*-12-*-*-*-*-*-*-*");
2715  if (font){
2716  style = gtk_style_copy(gtk_widget_get_style (bugtrack));
2717  gdk_font_unref(style->font);
2718  style->font=font; /*no ref since transfert*/
2719  font=NULL;
2720  gtk_widget_set_style(bugtrack,style);
2721  }
2722 #endif
2723  gtk_box_pack_start (GTK_BOX (hbox),bugtrack, TRUE, TRUE, 0);
2724  gtk_widget_show (bugtrack);
2725  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (bugtrack)->vadj);
2726  gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0);
2727  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2728  gtk_widget_show (vscrollbar);
2729  gtk_widget_show (hbox);
2730  hbox = gtk_hbox_new(FALSE, 2);
2731  bugbutton = gtk_button_new_with_label ("Close");
2732  gtk_signal_connect_object (GTK_OBJECT (bugbutton), "clicked",
2733  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2734  GTK_OBJECT (gtkwin_bug));
2735  gtk_box_pack_start (GTK_BOX (hbox), bugbutton, TRUE, FALSE, 0);
2736  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2737  gtk_widget_show (bugbutton);
2738  gtk_widget_show (hbox);
2739 
2740  gtk_widget_show (vbox);
2741  gtk_widget_show (gtkwin_bug);
2742  gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black,
2743  NULL, VERSION_INFO , -1);
2744  gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black,
2745  NULL, text , -1);
2746 
2747  gtk_text_insert (GTK_TEXT (buglabel), NULL, &buglabel->style->black,
2748  NULL, "\n\nVersion Information\n" , -1);
2749 
2750 
2751  gtk_adjustment_set_value(GTK_TEXT(buglabel)->vadj, 0.0);
2752  }
2753  else {
2754  gdk_window_raise (gtkwin_bug->window);
2755  }
2756 }
2757 
2758 void cclist_button_event(GtkWidget *gtklist, gint row, gint column, GdkEventButton *event) {
2759  gchar *buf;
2760  if (event->button==1) {
2761  gtk_clist_get_text (GTK_CLIST(cclist), row, 0, &buf);
2762  gtk_label_set (GTK_LABEL(cnumentrytext), buf);
2763  gtk_clist_get_text (GTK_CLIST(cclist), row, 1, &buf);
2764  gtk_entry_set_text (GTK_ENTRY(ckeyentrytext), buf);
2765  gtk_clist_get_text (GTK_CLIST(cclist), row, 3, &buf);
2766  gtk_entry_set_text (GTK_ENTRY(cmodentrytext), buf);
2767  gtk_clist_get_text (GTK_CLIST(cclist), row, 4, &buf);
2768  gtk_entry_set_text (GTK_ENTRY(ckentrytext), buf);
2769  }
2770 }
2771 
2772 
2773 void disconnect(GtkWidget *widget) {
2774 #ifdef WIN32
2775  closesocket(csocket.fd);
2776 #else
2777  close(csocket.fd);
2778 #endif
2779  csocket.fd = -1;
2780  if (csocket_fd) {
2781  gdk_input_remove(csocket_fd);
2782  csocket_fd=0;
2783  gtk_main_quit();
2784  }
2786 }
2787 
2788 /* Ok, simplistic help system. Just put the text file up in a scrollable window */
2789 
2790 static void shelpdialog(GtkWidget *widget) {
2791 #include "help/shelp.h"
2792  GtkWidget *vbox;
2793  GtkWidget *hbox;
2794  GtkWidget *shelptext;
2795  GtkWidget *helpbutton;
2796  GtkWidget *vscrollbar;
2797  /* GtkStyle *style;*/
2798 
2799  if(!gtkwin_shelp) {
2800 
2801  gtkwin_shelp = gtk_window_new (GTK_WINDOW_DIALOG);
2802  gtk_window_position (GTK_WINDOW (gtkwin_shelp), GTK_WIN_POS_CENTER);
2803  gtk_widget_set_usize (gtkwin_shelp,400,300);
2804  gtk_window_set_title (GTK_WINDOW (gtkwin_shelp), "Crossfire Server Help");
2805  gtk_window_set_policy (GTK_WINDOW (gtkwin_shelp), TRUE, TRUE, FALSE);
2806 
2807  gtk_signal_connect (GTK_OBJECT (gtkwin_shelp), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_shelp);
2808 
2809  gtk_container_border_width (GTK_CONTAINER (gtkwin_shelp), 0);
2810  vbox = gtk_vbox_new(FALSE, 2);
2811  gtk_container_add (GTK_CONTAINER(gtkwin_shelp),vbox);
2812  hbox = gtk_hbox_new(FALSE, 2);
2813  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2814 
2815  shelptext = gtk_text_new (NULL, NULL);
2816  gtk_text_set_editable (GTK_TEXT (shelptext), FALSE);
2817  gtk_box_pack_start (GTK_BOX (hbox),shelptext, TRUE, TRUE, 0);
2818  gtk_widget_show (shelptext);
2819 
2820  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (shelptext)->vadj);
2821  gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0);
2822 
2823  gtk_widget_show (vscrollbar);
2824  gtk_widget_show (hbox);
2825 
2826  hbox = gtk_hbox_new(FALSE, 2);
2827 
2828  helpbutton = gtk_button_new_with_label ("Close");
2829  gtk_signal_connect_object (GTK_OBJECT (helpbutton), "clicked",
2830  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2831  GTK_OBJECT (gtkwin_shelp));
2832  gtk_box_pack_start (GTK_BOX (hbox), helpbutton, TRUE, FALSE, 0);
2833  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2834  gtk_widget_show (helpbutton);
2835  gtk_widget_show (hbox);
2836 
2837  gtk_widget_show (vbox);
2838  gtk_widget_show (gtkwin_shelp);
2839  gtk_text_insert (GTK_TEXT (shelptext), NULL, &shelptext->style->black, NULL, text , -1);
2840  }
2841  else {
2842  gdk_window_raise (gtkwin_shelp->window);
2843  }
2844 }
2845 
2846 /* Various routines for setting modes by menu choices. */
2847 static void new_menu_pickup(GtkWidget *button, int val)
2848 {
2849  char modestr[128];
2850  unsigned int old_pickup = pickup_mode;
2851 
2852  /* widget is GtkCheckMenuItem */
2853  if(GTK_CHECK_MENU_ITEM (button)->active) {
2855  if (val != PU_NEWMODE)
2857  } else pickup_mode=pickup_mode&~val;
2858 
2859 
2860  if (old_pickup == pickup_mode)
2861  return;
2862 
2863 #if 0
2864  fprintf(stderr,"val=0x%8x\n",val);
2865  fprintf(stderr,"mode=0x%8x\n",pmode);
2866 #endif
2867 
2868  sprintf(modestr,"bind pickup %u",pickup_mode);
2869  draw_info("To set this pickup mode to a key, use:",NDI_BLACK);
2870  draw_info(modestr,NDI_BLACK);
2871  sprintf(modestr,"pickup %u",pickup_mode);
2872  send_command(modestr, -1, 0);
2873 }
2874 
2875 
2876 static void menu_pickup0(void) {
2877  pickup_mode = 0;
2878  send_command("pickup 0", -1, 0);
2879 }
2880 
2881 static void menu_pickup1(void) {
2882  pickup_mode = 1;
2883  send_command("pickup 1", -1, 0);
2884 }
2885 
2886 static void menu_pickup2(void) {
2887  pickup_mode = 2;
2888  send_command("pickup 2", -1, 0);
2889 }
2890 
2891 static void menu_pickup3(void) {
2892  pickup_mode = 3;
2893  send_command("pickup 3", -1, 0);
2894 }
2895 
2896 static void menu_pickup4(void) {
2897  pickup_mode = 4;
2898  send_command("pickup 4", -1, 0);
2899 }
2900 
2901 static void menu_pickup5(void) {
2902  pickup_mode = 5;
2903  send_command("pickup 5", -1, 0);
2904 
2905 }
2906 
2907 static void menu_pickup6(void) {
2908  pickup_mode = 6;
2909  send_command("pickup 6", -1, 0);
2910 }
2911 
2912 static void menu_pickup7(void) {
2913  pickup_mode = 7;
2914  send_command("pickup 7", -1, 0);
2915 }
2916 
2917 static void menu_pickup10(void) {
2918  pickup_mode = 10;
2919  send_command("pickup 10", -1, 0);
2920 }
2921 
2922 
2923 
2924 static void menu_who(void) {
2925  extended_command("who");
2926 }
2927 
2928 static void menu_apply(void) {
2929  extended_command("apply");
2930 }
2931 
2932 static void menu_cast(void) {
2933  gtk_entry_set_text(GTK_ENTRY(entrytext),"cast ");
2934  gtk_widget_grab_focus (GTK_WIDGET(entrytext));
2935 }
2936 
2937 static void menu_search(void) {
2938  extended_command("search");
2939 }
2940 
2941 static void menu_disarm(void) {
2942  extended_command("disarm");
2943 }
2944 
2945 static void spellinventory_redraw(GtkWidget* list, GdkEventVisibility* event, gpointer view_x) {
2946  item* ob;
2947  char buffer[2][MAX_BUF];
2948  char* columns[2];
2949  gint row, selected = -1;
2950 
2951  if (GTK_CLIST(list)->selection != NULL)
2952  selected = GPOINTER_TO_INT(GTK_CLIST(list)->selection->data);
2953 
2954  gtk_clist_freeze(GTK_CLIST(list));
2955  gtk_clist_clear(GTK_CLIST(list));
2956 
2957  columns[0] = buffer[0];
2958  columns[1] = buffer[1];
2959 
2960  for (ob = cpl.ob->inv; ob != NULL; ob = ob->next) {
2961  if (!can_write_spell_on(ob))
2962  continue;
2963  snprintf(buffer[0], sizeof(buffer[0]), " ");
2964  snprintf(buffer[1], sizeof(buffer[1]), ob->d_name);
2965  row = gtk_clist_append(GTK_CLIST(list), columns);
2966  gtk_clist_set_pixmap (GTK_CLIST (list), row, 0,
2967  (GdkPixmap*)pixmaps[ob->face]->icon_image,
2968  (GdkBitmap*)pixmaps[ob->face]->icon_mask);
2969  gtk_clist_set_row_data (GTK_CLIST(list), row, ob);
2970  }
2971 
2972  gtk_clist_thaw(GTK_CLIST(list));
2973 
2974  if (selected != -1) {
2975  gtk_clist_select_row(GTK_CLIST(list), selected, 1);
2976  gtk_clist_moveto(GTK_CLIST(list), selected, 0, 0, 0);
2977  }
2978 }
2979 
2980 static GtkWidget *gtkwin_spell = NULL; /* Spell window */
2981 static GtkWidget *description = NULL; /* The text box containing spell description */
2982 static GtkWidget *list = NULL;
2983 static GtkWidget *spelloptions = NULL; /* Text box with extra options to pass to the spell */
2984 GtkWidget *spellinventory = NULL; /* List containing inventory for spell inscription. Not static because
2985  will be changed by inventory.c*/
2986 
2987 static void click_inscribe_spell(void) {
2988  int selection;
2989  item *scroll;
2990  Spell* spell;
2991 
2992  if (GTK_CLIST(spellinventory)->selection != NULL && GTK_CLIST(list)->selection != NULL) {
2993  selection = GPOINTER_TO_INT(GTK_CLIST(spellinventory)->selection->data);
2994  scroll = (item*)gtk_clist_get_row_data(GTK_CLIST(spellinventory), selection);
2995 
2996  selection = GPOINTER_TO_INT(GTK_CLIST(list)->selection->data);
2997  spell = (Spell*)gtk_clist_get_row_data(GTK_CLIST(list), selection);
2998 
2999  inscribe_magical_scroll(scroll, spell);
3000  }
3001 }
3002 
3003 static void select_spell_event(GtkWidget *gtklist, gint row, gint column,
3004  GdkEventButton *event) {
3005 
3006  char command[MAX_BUF], message[MAX_BUF];
3007  Spell *spell = gtk_clist_get_row_data (GTK_CLIST(gtklist), row);
3008  char *options = NULL;
3009 
3010  if (!event) return; /* We have nothing to do */
3011  /* Any click will select the spell, and show it's description */
3012  gtk_text_freeze(GTK_TEXT(description));
3013  gtk_text_set_point(GTK_TEXT(description), 0);
3014  gtk_text_forward_delete(GTK_TEXT(description), gtk_text_get_length(GTK_TEXT(description)));
3015  sprintf(message, "%s - level %d %s spell\n\n%s", spell->name, spell->level,
3016  spell->skill?spell->skill:"generic", spell->message);
3017  gtk_text_insert(GTK_TEXT(description), NULL, NULL, NULL, message, -1);
3018  gtk_text_thaw(GTK_TEXT(description));
3019  if (event->button==2) { /* On middle click, also invoke the spell */
3020  options = gtk_editable_get_chars(GTK_EDITABLE(spelloptions), 0, -1);
3021  sprintf(command, "invoke %d %s", spell->tag, options);
3022  send_command(command, -1, 1);
3023  g_free(options);
3024  }
3025  else if (event->button==3) { /* On right click, also cast the spell */
3026  options = gtk_editable_get_chars(GTK_EDITABLE(spelloptions), 0, -1);
3027  sprintf(command, "cast %d %s", spell->tag, options);
3028  send_command(command, -1, 1);
3029  g_free(options);
3030  }
3031 }
3032 
3033 static void update_spell_list(int force) {
3034  gint row;
3035  char buffer[3][MAX_BUF];
3036  char *columns[3];
3037  Spell *spell;
3038  PixmapInfo * pixmap;
3039 
3040  /* Only update if we have to */
3041  if (!force && !cpl.spells_updated) return;
3042  if (!gtkwin_spell || !GTK_IS_CLIST(list) || !GTK_WIDGET_VISIBLE(gtkwin_spell)) return;
3043 
3044  gtk_clist_freeze(GTK_CLIST(list));
3045 
3046  /* We are about to recreate the entire spell list, so remove the existing one first */
3047  gtk_clist_clear(GTK_CLIST(list));
3048 
3049  for (spell = cpl.spelldata; spell; spell=spell->next) {
3050  if (!spell) break;
3051  pixmap = pixmaps[spell->face];
3052  buffer[2][0]='\0';
3053  buffer[0][0]='\0';
3054  strcpy(buffer[1], spell->name);
3055  columns[0] = buffer[0];
3056  columns[1] = buffer[1];
3057  columns[2] = buffer[2];
3058  if (spell->sp) sprintf(buffer[2], "%d mana ", spell->sp);
3059  if (spell->grace) sprintf(buffer[2]+strlen(buffer[2]), "%d grace ", spell->grace);
3060  if (spell->dam) sprintf(buffer[2]+strlen(buffer[2]), "%d damage ", spell->dam);
3061 
3062  /* The columns array doesn't yet contain the data we need, but we can't set the
3063  * row colour until we create the row, so we create the row with gtk_clist_append()
3064  * set the colour, then reset the text in the second column
3065  */
3066  row = gtk_clist_append(GTK_CLIST(list), columns);
3067  gtk_clist_set_row_data(GTK_CLIST(list), row, spell);
3068  if (spell->path & cpl.stats.denied) {
3069  gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_RED]);
3070  strcat(buffer[2], "(DENIED) ");
3071  }
3072  else if (spell->path & cpl.stats.attuned) {
3073  gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_GREEN]);
3074  strcat(buffer[2], "(attuned) ");
3075  }
3076  else if (spell->path & cpl.stats.repelled) {
3077  gtk_clist_set_background (GTK_CLIST(list), row, &root_color[NDI_ORANGE]);
3078  strcat(buffer[2], "(repelled) ");
3079  }
3080  gtk_clist_set_text(GTK_CLIST(list), row, 2, columns[2]);
3081  gtk_clist_set_pixmap (GTK_CLIST (list), row, 0,
3082  (GdkPixmap*)pixmap->icon_image, (GdkBitmap*)pixmap->icon_mask);
3083  }
3084  gtk_clist_thaw(GTK_CLIST(list));
3085  cpl.spells_updated =0;
3086 }
3087 
3088 static void menu_spells(void) {
3089  GtkWidget * scroll_window;
3090  GtkStyle * liststyle;
3091  GtkWidget *cancelbutton;
3092  GtkWidget * vbox;
3093  GtkWidget * optionsbox;
3094  GtkWidget * spelloptionslabel;
3095  GtkWidget * notebook;
3096  GtkWidget * label;
3097  GtkWidget * frame;
3098  GtkWidget * inscribebutton;
3099  GtkWidget * inscribewindow;
3100  gchar *titles[] = {" ", "Name", "Cost"};
3101  gchar *titles_inv[] = {" ", "Name"};
3102 
3103  if (gtkwin_spell && GTK_IS_CLIST(list)) {
3104  /* The window is already created, re-present it */
3105  if (GTK_WIDGET_VISIBLE(gtkwin_spell)) {
3106  gdk_window_raise(gtkwin_spell->window);
3107  return;
3108  }
3109 
3110  /* The window is hidden at the moment, so we don't need to recreate it.
3111  * We can merely reshow it, but the spell list won't have updated while
3112  * it was hidden so we have to force an update */
3113  gtk_widget_show_all(gtkwin_spell);
3114  update_spell_list(1);
3115  return;
3116  }
3117 
3118  /* We can't use an existing version, so we must create a new one. First we
3119  * will deal with the window itself */
3120  gtkwin_spell = gtk_window_new (GTK_WINDOW_DIALOG);
3121  gtk_window_set_default_size(GTK_WINDOW(gtkwin_spell), 400+image_size, 400+image_size);
3122  gtk_window_set_title(GTK_WINDOW (gtkwin_spell), "Cast Spell");
3123 
3124  /* Now for its contents: first we'll deal with the options widget */
3125  spelloptions = gtk_entry_new();
3126  spelloptionslabel = gtk_label_new("Spell Options:");
3127  optionsbox = gtk_hbox_new(FALSE, 2);
3128  gtk_box_pack_start(GTK_BOX(optionsbox), spelloptionslabel, FALSE, FALSE, 0);
3129  gtk_box_pack_start(GTK_BOX(optionsbox), spelloptions, TRUE, TRUE, 0);
3130 
3131  /* rNw the list scroll window */
3132  scroll_window = gtk_scrolled_window_new (0,0);
3133  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
3134  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3135 
3136  /* And the spell list itself */
3137  list = gtk_clist_new_with_titles(3, titles);
3138  gtk_clist_set_column_width(GTK_CLIST(list), 1, image_size);
3139  gtk_clist_set_column_width(GTK_CLIST(list), 1, 200);
3140  gtk_clist_set_column_width(GTK_CLIST(list), 2, 200);
3141  gtk_clist_set_selection_mode(GTK_CLIST(list) , GTK_SELECTION_BROWSE);
3142  gtk_clist_set_row_height (GTK_CLIST(list), image_size);
3143  liststyle = gtk_rc_get_style(list);
3144  if (liststyle) {
3145  liststyle->bg[GTK_STATE_SELECTED] = gdk_grey;
3146  liststyle->fg[GTK_STATE_SELECTED] = gdk_black;
3147  gtk_widget_set_style (list, liststyle);
3148  }
3149  /* Set the actions for the mouse buttons to trigger the callback function */
3150  gtk_clist_set_button_actions(GTK_CLIST(list), 1, GTK_BUTTON_SELECTS);
3151  gtk_clist_set_button_actions(GTK_CLIST(list), 2, GTK_BUTTON_SELECTS);
3152  gtk_signal_connect(GTK_OBJECT(list), "select_row",
3153  GTK_SIGNAL_FUNC(select_spell_event), NULL);
3154 
3155  /* With all that done, we can now add it to the scroll window */
3156  gtk_container_add(GTK_CONTAINER(scroll_window), list);
3157 
3158  /* Now we'll create the description box */
3159  description = gtk_text_new(NULL, NULL);
3160  gtk_text_set_editable(GTK_TEXT (description), FALSE);
3161 
3162  /* Finally add a close button to the window */
3163  cancelbutton = gtk_button_new_with_label("Close");
3164  gtk_signal_connect_object (GTK_OBJECT (cancelbutton), "clicked",
3165  GTK_SIGNAL_FUNC(gtk_widget_hide_all), GTK_OBJECT (gtkwin_spell));
3166 
3167  notebook = gtk_notebook_new ();
3168  gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP );
3169 
3170  label = gtk_label_new ("Information");
3171  gtk_widget_show (label);
3172 
3173  frame = gtk_frame_new("Spell information");
3174  gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
3175  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
3176  vbox = gtk_vbox_new(FALSE, 0);
3177  gtk_box_pack_start(GTK_BOX(vbox), optionsbox, FALSE, FALSE, 0);
3178  gtk_box_pack_start(GTK_BOX(vbox), description, TRUE, TRUE, 0);
3179  gtk_container_add (GTK_CONTAINER(frame), vbox);
3180 
3181  /* Start of inventory list for inscription */
3182  if (command_inscribe) {
3183  label = gtk_label_new ("Inscribe");
3184  gtk_widget_show (label);
3185 
3186  frame = gtk_frame_new("Inscribe a spell");
3187  gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
3188  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), frame, label);
3189  vbox = gtk_vbox_new(FALSE, 0);
3190  label = gtk_label_new ("Choose the item to write on:");
3191  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
3192 
3193  inscribewindow = gtk_scrolled_window_new (0,0);
3194  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(inscribewindow),
3195  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3196 
3197  spellinventory = gtk_clist_new_with_titles(2, titles_inv);
3198  gtk_clist_set_column_width(GTK_CLIST(spellinventory), 0, image_size);
3199  gtk_clist_set_selection_mode(GTK_CLIST(spellinventory) , GTK_SELECTION_BROWSE);
3200  gtk_clist_set_row_height (GTK_CLIST(spellinventory), image_size);
3201  liststyle = gtk_rc_get_style(spellinventory);
3202  if (liststyle) {
3203  liststyle->bg[GTK_STATE_SELECTED] = gdk_grey;
3204  liststyle->fg[GTK_STATE_SELECTED] = gdk_black;
3205  gtk_widget_set_style (spellinventory, liststyle);
3206  }
3207  gtk_signal_connect(GTK_OBJECT(spellinventory),
3208  "visibility-notify-event",
3209  (GtkSignalFunc)spellinventory_redraw, NULL);
3210  gtk_widget_add_events(spellinventory, GDK_VISIBILITY_NOTIFY_MASK);
3211 
3212  gtk_container_add(GTK_CONTAINER(inscribewindow), spellinventory);
3213  gtk_box_pack_start(GTK_BOX(vbox), inscribewindow, TRUE, TRUE, 0);
3214 
3215  inscribebutton = gtk_button_new_with_label("Inscribe");
3216  gtk_signal_connect_object (GTK_OBJECT (inscribebutton), "clicked",
3217  GTK_SIGNAL_FUNC(click_inscribe_spell), NULL);
3218  gtk_box_pack_start(GTK_BOX(vbox), inscribebutton, FALSE, FALSE, 0);
3219 
3220  gtk_container_add (GTK_CONTAINER(frame), vbox);
3221  }
3222  /* End of inscription logic */
3223 
3224  /* vbox holds all the widgets we just created, in order */
3225  vbox = gtk_vbox_new(FALSE, 2);
3226 
3227  /* Ok, time to pack it all up */
3228  gtk_container_add(GTK_CONTAINER(gtkwin_spell), vbox);
3229  gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0);
3230 
3231  gtk_box_pack_start (GTK_BOX(vbox),notebook, TRUE, TRUE, 0);
3232 
3233  gtk_box_pack_start(GTK_BOX(vbox), cancelbutton, FALSE, FALSE, 0);
3234 
3235  gtk_widget_show_all(gtkwin_spell);
3236 
3237  /* Let's add the spells to the list now */
3238  update_spell_list(1);
3239 }
3240 
3241 void menu_clear(void) {
3242  guint size;
3243 
3244  size = gtk_text_get_length(GTK_TEXT (gtkwin_info_text));
3245  gtk_text_freeze (GTK_TEXT (gtkwin_info_text));
3246  gtk_text_set_point(GTK_TEXT (gtkwin_info_text), 0);
3247  gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text), size );
3248  gtk_text_thaw (GTK_TEXT (gtkwin_info_text));
3249 
3250 #ifdef WIN32
3251  if ( gtkwin_info_text2 )
3252  {
3253 #endif
3254  size = gtk_text_get_length(GTK_TEXT (gtkwin_info_text2));
3255  gtk_text_freeze (GTK_TEXT (gtkwin_info_text2));
3256  gtk_text_set_point(GTK_TEXT (gtkwin_info_text2), 0);
3257  gtk_text_forward_delete (GTK_TEXT (gtkwin_info_text2), size );
3258  gtk_text_thaw (GTK_TEXT (gtkwin_info_text2));
3259 #ifdef WIN32
3260  }
3261 #endif
3262 }
3263 
3264 static void sexit(void)
3265 {
3266  extended_command("quit");
3267 }
3268 
3269 void client_exit(void) {
3270  LOG(LOG_INFO,"gtk::client_exit","Exiting with return value 0.");
3271 #ifdef WIN32
3272  script_killall();
3273 #endif
3274  exit(0);
3275 }
3276 
3277 /* To keep track of pickup menus, and be able to check/uncheck them. */
3278 static GtkWidget* pickup_menus[43];
3279 static int pickup_value[43];
3280 static int pickup_count = 0;
3281 
3282 /* get_menu_display
3283  * This sets up menus
3284  */
3285 
3286 static int get_menu_display (GtkWidget *box) {
3287  GtkWidget *filemenu;
3288  GtkWidget *actionmenu;
3289  GtkWidget *pickupmenu;
3290  GtkWidget *newpickupmenu;
3291  GtkWidget *ratiopickupmenu;
3292  GtkWidget *weaponpickupmenu;
3293  GtkWidget *armourpickupmenu;
3294  GtkWidget *bookspickupmenu;
3295  GtkWidget *clientmenu;
3296  GtkWidget *helpmenu;
3297  GtkWidget *menu_bar;
3298  GtkWidget *root_filemenu;
3299  GtkWidget *root_helpmenu;
3300  GtkWidget *root_actionmenu;
3301  /* GtkWidget *sub_pickupmenu;*/
3302  GtkWidget *root_clientmenu;
3303  GtkWidget *menu_items;
3304  GtkWidget *pickup_menu_item;
3305  GtkWidget *newpickup_menu_item;
3306  GtkWidget *ratiopickup_menu_item;
3307  GtkWidget *weaponpickup_menu_item;
3308  GtkWidget *armourpickup_menu_item;
3309  GtkWidget *bookspickup_menu_item;
3310  GSList *pickupgroup;
3311  GSList *ratiopickupgroup;
3312  int i;
3313  char menustring[128];
3314 
3315 
3316  /* Init the menu-widget, and remember -- never
3317  * gtk_show_widget() the menu widget!!
3318  * This is the menu that holds the menu items, the one that
3319  * will pop up when you click on the "Root Menu" in the app */
3320  filemenu = gtk_menu_new();
3321 
3322  /* Next we make a little loop that makes three menu-entries for "test-menu".
3323  * Notice the call to gtk_menu_append. Here we are adding a list of
3324  * menu items to our menu. Normally, we'd also catch the "clicked"
3325  * signal on each of the menu items and setup a callback for it,
3326  * but it's omitted here to save space. */
3327 
3328  menu_items = gtk_tearoff_menu_item_new ();
3329  gtk_menu_append (GTK_MENU (filemenu), menu_items);
3330  gtk_widget_show (menu_items);
3331 
3332  menu_items = gtk_menu_item_new_with_label("Save config");
3333  gtk_menu_append(GTK_MENU (filemenu), menu_items);
3334  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3335  GTK_SIGNAL_FUNC(save_defaults), NULL);
3336  gtk_widget_show(menu_items);
3337 
3338  menu_items = gtk_menu_item_new_with_label("Save window positions");
3339  gtk_menu_append(GTK_MENU (filemenu), menu_items);
3340  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3341  GTK_SIGNAL_FUNC(save_winpos), NULL);
3342  gtk_widget_show(menu_items);
3343 
3344  menu_items = gtk_menu_item_new ();
3345  gtk_menu_append(GTK_MENU (filemenu), menu_items);
3346  gtk_widget_show(menu_items);
3347 
3348 
3349  menu_items = gtk_menu_item_new_with_label("Quit character");
3350  gtk_menu_append(GTK_MENU (filemenu), menu_items);
3351  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3352  GTK_SIGNAL_FUNC(sexit), NULL);
3353  gtk_widget_show(menu_items);
3354 
3355  menu_items = gtk_menu_item_new_with_label("Quit client");
3356  gtk_menu_append(GTK_MENU (filemenu), menu_items);
3357  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3358  GTK_SIGNAL_FUNC(client_exit), NULL);
3359  gtk_widget_show(menu_items);
3360 
3361  /* This is the root menu, and will be the label
3362  * displayed on the menu bar. There won't be a signal handler attached,
3363  * as it only pops up the rest of the menu when pressed. */
3364  root_filemenu = gtk_menu_item_new_with_label("File");
3365 
3366  gtk_widget_show(root_filemenu);
3367 
3368  /* Now we specify that we want our newly created "menu" to be the menu
3369  * for the "root menu" */
3370  gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_filemenu), filemenu);
3371 
3372  /* Do the clientmenu */
3373 
3374  clientmenu = gtk_menu_new();
3375 
3376  /* menu_items = gtk_menu_item_new_with_label("Navigator");
3377  gtk_menu_append(GTK_MENU (clientmenu), menu_items);
3378  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3379  GTK_SIGNAL_FUNC(navbut), NULL);
3380  gtk_widget_show(menu_items);*/
3381 
3382  menu_items = gtk_tearoff_menu_item_new ();
3383  gtk_menu_append (GTK_MENU (clientmenu), menu_items);
3384  gtk_widget_show (menu_items);
3385 
3386  menu_items = gtk_menu_item_new_with_label("Clear info");
3387  gtk_menu_append(GTK_MENU (clientmenu), menu_items);
3388  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3389  GTK_SIGNAL_FUNC(menu_clear), NULL);
3390  gtk_widget_show(menu_items);
3391 
3392 
3393  menu_items = gtk_menu_item_new_with_label("Spells");
3394  gtk_menu_append(GTK_MENU (clientmenu), menu_items);
3395  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3396  GTK_SIGNAL_FUNC(menu_spells), NULL);
3397  gtk_widget_show(menu_items);
3398 
3399  menu_items = gtk_menu_item_new_with_label("Configure");
3400  gtk_menu_append(GTK_MENU (clientmenu), menu_items);
3401  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3402  GTK_SIGNAL_FUNC(configdialog), NULL);
3403  gtk_widget_show(menu_items);
3404 
3405 
3406  menu_items = gtk_menu_item_new_with_label("Disconnect");
3407  gtk_menu_append(GTK_MENU (clientmenu), menu_items);
3408  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3409  GTK_SIGNAL_FUNC(disconnect), NULL);
3410  gtk_widget_show(menu_items);
3411 
3412 
3413  root_clientmenu = gtk_menu_item_new_with_label("Client");
3414 
3415  gtk_widget_show(root_clientmenu);
3416  gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_clientmenu), clientmenu);
3417 
3418  /* Do the actionmenu */
3419 
3420  actionmenu = gtk_menu_new();
3421 
3422  menu_items = gtk_tearoff_menu_item_new ();
3423  gtk_menu_append (GTK_MENU (actionmenu), menu_items);
3424  gtk_widget_show (menu_items);
3425 
3426  menu_items = gtk_menu_item_new_with_label("Who");
3427  gtk_menu_append(GTK_MENU (actionmenu), menu_items);
3428  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3429  GTK_SIGNAL_FUNC(menu_who), NULL);
3430  gtk_widget_show(menu_items);
3431 
3432  menu_items = gtk_menu_item_new_with_label("Cast...");
3433  gtk_menu_append(GTK_MENU (actionmenu), menu_items);
3434  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3435  GTK_SIGNAL_FUNC(menu_cast), NULL);
3436  gtk_widget_show(menu_items);
3437 
3438  menu_items = gtk_menu_item_new_with_label("Apply");
3439  gtk_menu_append(GTK_MENU (actionmenu), menu_items);
3440  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3441  GTK_SIGNAL_FUNC(menu_apply), NULL);
3442  gtk_widget_show(menu_items);
3443 
3444  pickup_menu_item = gtk_menu_item_new_with_label("Pickup");
3445  gtk_menu_append(GTK_MENU (actionmenu), pickup_menu_item);
3446  /* gtk_signal_connect_object(GTK_OBJECT(pickup_menu_item), "activate",
3447  GTK_SIGNAL_FUNC(menu_apply), NULL);*/
3448  gtk_widget_show(pickup_menu_item);
3449 
3450  newpickup_menu_item = gtk_menu_item_new_with_label("NEWPickup");
3451  gtk_menu_append(GTK_MENU (actionmenu), newpickup_menu_item);
3452  gtk_widget_show(newpickup_menu_item);
3453 
3454  menu_items = gtk_menu_item_new_with_label("Search");
3455  gtk_menu_append(GTK_MENU (actionmenu), menu_items);
3456  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3457  GTK_SIGNAL_FUNC(menu_search), NULL);
3458  gtk_widget_show(menu_items);
3459 
3460  menu_items = gtk_menu_item_new_with_label("Disarm");
3461  gtk_menu_append(GTK_MENU (actionmenu), menu_items);
3462  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3463  GTK_SIGNAL_FUNC(menu_disarm), NULL);
3464  gtk_widget_show(menu_items);
3465 
3466 
3467  root_actionmenu = gtk_menu_item_new_with_label("Action");
3468 
3469  gtk_widget_show(root_actionmenu);
3470  gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_actionmenu), actionmenu);
3471 
3472  /* Do the submenu */
3473 
3474  pickupmenu = gtk_menu_new();
3475 
3476  /* This allows you to change your pickup status. Eight different modes for pick up exist: ``don't pick up'',``pick up 1
3477 item'', ``pick up 1 item and stop'', ``stop before picking up'', ``pick up all items'', pick up all items and stop'',
3478 ``pick up all magic items'', ``pick up all coins and gems''. Whenever you move over a pile of stuff your pickup*/
3479  pickupgroup=NULL;
3480 
3481  menu_items = gtk_tearoff_menu_item_new ();
3482  gtk_menu_append (GTK_MENU (pickupmenu), menu_items);
3483  gtk_widget_show (menu_items);
3484 
3485  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Don't pick up");
3486  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3487  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3488  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3489  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3490  GTK_SIGNAL_FUNC(menu_pickup0), NULL);
3491  gtk_widget_show(menu_items);
3492 
3493  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up 1 item");
3494  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3495  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3496  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3497  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3498  GTK_SIGNAL_FUNC(menu_pickup1), NULL);
3499  gtk_widget_show(menu_items);
3500 
3501 
3502  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up 1 item and stop");
3503  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3504  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3505  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3506  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3507  GTK_SIGNAL_FUNC(menu_pickup2), NULL);
3508  gtk_widget_show(menu_items);
3509 
3510  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Stop before picking up.");
3511  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3512  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3513  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3514  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3515  GTK_SIGNAL_FUNC(menu_pickup3), NULL);
3516  gtk_widget_show(menu_items);
3517 
3518  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all items.");
3519  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3520  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3521  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3522  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3523  GTK_SIGNAL_FUNC(menu_pickup4), NULL);
3524  gtk_widget_show(menu_items);
3525 
3526  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all items and stop.");
3527  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3528  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3529  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3530  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3531  GTK_SIGNAL_FUNC(menu_pickup5), NULL);
3532  gtk_widget_show(menu_items);
3533 
3534  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all magic items.");
3535  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3536  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3537  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3538  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3539  GTK_SIGNAL_FUNC(menu_pickup6), NULL);
3540  gtk_widget_show(menu_items);
3541 
3542  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pick up all coins and gems.");
3543  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3544  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3545  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3546  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3547  GTK_SIGNAL_FUNC(menu_pickup7), NULL);
3548  gtk_widget_show(menu_items);
3549 
3550  menu_items = gtk_radio_menu_item_new_with_label(pickupgroup, "Pickup silver and higher value/weight.");
3551  pickupgroup = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_items));
3552  gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menu_items), TRUE);
3553  gtk_menu_append(GTK_MENU (pickupmenu), menu_items);
3554  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3555  GTK_SIGNAL_FUNC(menu_pickup10), NULL);
3556  gtk_widget_show(menu_items);
3557 
3558 
3559  /* sub_pickupmenu = gtk_menu_item_new_with_label("Action");
3560 
3561  gtk_widget_show(sub_pickupmenu);*/
3562  gtk_menu_item_set_submenu(GTK_MENU_ITEM (pickup_menu_item), pickupmenu);
3563 /* ENDPICKUP */
3564 
3565 /* --------------------------------------------------------------------- */
3566 /* --------------------------------------------------------------------- */
3567 /* --------------------------------------------------------------------- */
3568 /* --------------------------------------------------------------------- */
3569 /* --------------------------------------------------------------------- */
3570 
3571  /* Root of the NEWPickup menu */
3572  newpickupmenu = gtk_menu_new();
3573  gtk_menu_item_set_submenu(GTK_MENU_ITEM(newpickup_menu_item), newpickupmenu);
3574 
3575  menu_items = gtk_tearoff_menu_item_new();
3576  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3577  gtk_widget_show(menu_items);
3578 
3579  menu_items = gtk_check_menu_item_new_with_label("Enable NEW autopickup");
3580  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3581  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3582  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3583  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_NEWMODE));
3584  gtk_widget_show(menu_items);
3585  pickup_menus[pickup_count] = menu_items;
3586  pickup_value[pickup_count++] = PU_NEWMODE;
3587 
3588  menu_items = gtk_check_menu_item_new_with_label("Inhibit autopickup");
3589  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3590  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3591  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3592  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_INHIBIT));
3593  gtk_widget_show(menu_items);
3594  pickup_menus[pickup_count] = menu_items;
3595  pickup_value[pickup_count++] = PU_INHIBIT;
3596 
3597  menu_items = gtk_check_menu_item_new_with_label("Stop before pickup");
3598  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3599  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3600  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3601  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_STOP));
3602  gtk_widget_show(menu_items);
3603  pickup_menus[pickup_count] = menu_items;
3604  pickup_value[pickup_count++] = PU_STOP;
3605 
3606  menu_items = gtk_check_menu_item_new_with_label("Debug autopickup");
3607  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3608  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3609  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3610  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_DEBUG));
3611  gtk_widget_show(menu_items);
3612  pickup_menus[pickup_count] = menu_items;
3613  pickup_value[pickup_count++] = PU_DEBUG;
3614 
3615 
3616  /* The ratio pickup submenu */
3617  ratiopickupmenu = gtk_menu_new();
3618  ratiopickup_menu_item = gtk_menu_item_new_with_label("Weight/Value Ratio");
3619  gtk_menu_append(GTK_MENU(newpickupmenu), ratiopickup_menu_item);
3620  gtk_widget_show(ratiopickup_menu_item);
3621  gtk_menu_item_set_submenu(GTK_MENU_ITEM(ratiopickup_menu_item), ratiopickupmenu);
3622 
3623  ratiopickupgroup=NULL;
3624 
3625  menu_items = gtk_tearoff_menu_item_new();
3626  gtk_menu_append(GTK_MENU(ratiopickupmenu), menu_items);
3627  gtk_widget_show(menu_items);
3628 
3629  for (i=0;i<16;i++)
3630  {
3631  if (i==0) sprintf(menustring,"Ratio pickup OFF");
3632  else sprintf(menustring,"Ratio >= %d",i*5);
3633  menu_items = gtk_radio_menu_item_new_with_label(ratiopickupgroup, menustring);
3634  ratiopickupgroup = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menu_items));
3635  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3636  gtk_menu_append(GTK_MENU(ratiopickupmenu), menu_items);
3637  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3638  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(i));
3639  gtk_widget_show(menu_items);
3640  pickup_menus[pickup_count] = menu_items;
3641  pickup_value[pickup_count++] = i;
3642  }
3643 
3644 
3645  /* Weapon pickup menu */
3646  weaponpickupmenu = gtk_menu_new();
3647  weaponpickup_menu_item = gtk_menu_item_new_with_label("Weapons");
3648  gtk_menu_append(GTK_MENU(newpickupmenu), weaponpickup_menu_item);
3649  gtk_widget_show(weaponpickup_menu_item);
3650  gtk_menu_item_set_submenu(GTK_MENU_ITEM(weaponpickup_menu_item), weaponpickupmenu);
3651 
3652  menu_items = gtk_tearoff_menu_item_new();
3653  gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items);
3654  gtk_widget_show(menu_items);
3655 
3656  menu_items = gtk_check_menu_item_new_with_label("All weapons");
3657  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3658  gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items);
3659  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3660  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ALLWEAPON));
3661  gtk_widget_show(menu_items);
3662  pickup_menus[pickup_count] = menu_items;
3663  pickup_value[pickup_count++] = PU_ALLWEAPON;
3664 
3665  menu_items = gtk_check_menu_item_new_with_label("Missile Weapons");
3666  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3667  gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items);
3668  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3669  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MISSILEWEAPON));
3670  gtk_widget_show(menu_items);
3671  pickup_menus[pickup_count] = menu_items;
3672  pickup_value[pickup_count++] = PU_MISSILEWEAPON;
3673 
3674  menu_items = gtk_check_menu_item_new_with_label("Bows");
3675  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3676  gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items);
3677  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3678  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_BOW));
3679  gtk_widget_show(menu_items);
3680  pickup_menus[pickup_count] = menu_items;
3681  pickup_value[pickup_count++] = PU_BOW;
3682 
3683  menu_items = gtk_check_menu_item_new_with_label("Arrows");
3684  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3685  gtk_menu_append(GTK_MENU(weaponpickupmenu), menu_items);
3686  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3687  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ARROW));
3688  gtk_widget_show(menu_items);
3689  pickup_menus[pickup_count] = menu_items;
3690  pickup_value[pickup_count++] = PU_ARROW;
3691 
3692 
3693  /* Armour pickup menu */
3694  armourpickupmenu = gtk_menu_new();
3695  armourpickup_menu_item = gtk_menu_item_new_with_label("Armour");
3696  gtk_menu_append(GTK_MENU(newpickupmenu), armourpickup_menu_item);
3697  gtk_widget_show(armourpickup_menu_item);
3698  gtk_menu_item_set_submenu(GTK_MENU_ITEM(armourpickup_menu_item), armourpickupmenu);
3699 
3700  menu_items = gtk_tearoff_menu_item_new();
3701  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3702  gtk_widget_show(menu_items);
3703 
3704  menu_items = gtk_check_menu_item_new_with_label("Helmets");
3705  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3706  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3707  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3708  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_HELMET));
3709  gtk_widget_show(menu_items);
3710  pickup_menus[pickup_count] = menu_items;
3711  pickup_value[pickup_count++] = PU_HELMET;
3712 
3713  menu_items = gtk_check_menu_item_new_with_label("Shields");
3714  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3715  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3716  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3717  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SHIELD));
3718  gtk_widget_show(menu_items);
3719  pickup_menus[pickup_count] = menu_items;
3720  pickup_value[pickup_count++] = PU_SHIELD;
3721 
3722  menu_items = gtk_check_menu_item_new_with_label("Body Armour");
3723  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3724  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3725  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3726  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_ARMOUR));
3727  gtk_widget_show(menu_items);
3728  pickup_menus[pickup_count] = menu_items;
3729  pickup_value[pickup_count++] = PU_ARMOUR;
3730 
3731  menu_items = gtk_check_menu_item_new_with_label("Boots");
3732  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3733  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3734  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3735  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_BOOTS));
3736  gtk_widget_show(menu_items);
3737  pickup_menus[pickup_count] = menu_items;
3738  pickup_value[pickup_count++] = PU_BOOTS;
3739 
3740  menu_items = gtk_check_menu_item_new_with_label("Gloves");
3741  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3742  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3743  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3744  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_GLOVES));
3745  gtk_widget_show(menu_items);
3746  pickup_menus[pickup_count] = menu_items;
3747  pickup_value[pickup_count++] = PU_GLOVES;
3748 
3749  menu_items = gtk_check_menu_item_new_with_label("Cloaks");
3750  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3751  gtk_menu_append(GTK_MENU(armourpickupmenu), menu_items);
3752  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3753  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_CLOAK));
3754  gtk_widget_show(menu_items);
3755  pickup_menus[pickup_count] = menu_items;
3756  pickup_value[pickup_count++] = PU_CLOAK;
3757 
3758 
3759  /* Books pickup menu */
3760  bookspickupmenu = gtk_menu_new();
3761  bookspickup_menu_item = gtk_menu_item_new_with_label("Books");
3762  gtk_menu_append(GTK_MENU(newpickupmenu), bookspickup_menu_item);
3763  gtk_widget_show(bookspickup_menu_item);
3764  gtk_menu_item_set_submenu(GTK_MENU_ITEM(bookspickup_menu_item), bookspickupmenu);
3765 
3766  menu_items = gtk_tearoff_menu_item_new();
3767  gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items);
3768  gtk_widget_show(menu_items);
3769 
3770  menu_items = gtk_check_menu_item_new_with_label("Spellbooks");
3771  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3772  gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items);
3773  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3774  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SPELLBOOK));
3775  gtk_widget_show(menu_items);
3776  pickup_menus[pickup_count] = menu_items;
3777  pickup_value[pickup_count++] = PU_SPELLBOOK;
3778 
3779  menu_items = gtk_check_menu_item_new_with_label("Skillscrolls");
3780  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3781  gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items);
3782  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3783  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_SKILLSCROLL));
3784  gtk_widget_show(menu_items);
3785  pickup_menus[pickup_count] = menu_items;
3786  pickup_value[pickup_count++] = PU_SKILLSCROLL;
3787 
3788  menu_items = gtk_check_menu_item_new_with_label("Normal Books/Scrolls");
3789  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3790  gtk_menu_append(GTK_MENU(bookspickupmenu), menu_items);
3791  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3792  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_READABLES));
3793  gtk_widget_show(menu_items);
3794  pickup_menus[pickup_count] = menu_items;
3795  pickup_value[pickup_count++] = PU_READABLES;
3796 
3797 
3798  /* Continue with the rest of the stuff... */
3799 
3800  menu_items = gtk_check_menu_item_new_with_label("Food");
3801  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3802  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3803  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3804  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_FOOD));
3805  gtk_widget_show(menu_items);
3806  pickup_menus[pickup_count] = menu_items;
3807  pickup_value[pickup_count++] = PU_FOOD;
3808 
3809  menu_items = gtk_check_menu_item_new_with_label("Drinks");
3810  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3811  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3812  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3813  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_DRINK));
3814  gtk_widget_show(menu_items);
3815  pickup_menus[pickup_count] = menu_items;
3816  pickup_value[pickup_count++] = PU_DRINK;
3817 
3818  menu_items = gtk_check_menu_item_new_with_label("Flesh");
3819  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3820  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3821  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3822  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_FLESH));
3823  gtk_widget_show(menu_items);
3824  pickup_menus[pickup_count] = menu_items;
3825  pickup_value[pickup_count++] = PU_FLESH;
3826 
3827  menu_items = gtk_check_menu_item_new_with_label("Valuables (Money, Gems)");
3828  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3829  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3830  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3831  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_VALUABLES));
3832  gtk_widget_show(menu_items);
3833  pickup_menus[pickup_count] = menu_items;
3834  pickup_value[pickup_count++] = PU_VALUABLES;
3835 
3836  menu_items = gtk_check_menu_item_new_with_label("Keys");
3837  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3838  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3839  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3840  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_KEY));
3841  gtk_widget_show(menu_items);
3842  pickup_menus[pickup_count] = menu_items;
3843  pickup_value[pickup_count++] = PU_KEY;
3844 
3845  menu_items = gtk_check_menu_item_new_with_label("Magical Items");
3846  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3847  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3848  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3849  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MAGICAL));
3850  gtk_widget_show(menu_items);
3851  pickup_menus[pickup_count] = menu_items;
3852  pickup_value[pickup_count++] = PU_MAGICAL;
3853 
3854  menu_items = gtk_check_menu_item_new_with_label("Potions");
3855  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3856  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3857  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3858  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_POTION));
3859  gtk_widget_show(menu_items);
3860  pickup_menus[pickup_count] = menu_items;
3861  pickup_value[pickup_count++] = PU_POTION;
3862 
3863  menu_items = gtk_check_menu_item_new_with_label("Magic Devices");
3864  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3865  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3866  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3867  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_MAGIC_DEVICE));
3868  gtk_widget_show(menu_items);
3869  pickup_menus[pickup_count] = menu_items;
3870  pickup_value[pickup_count++] = PU_MAGIC_DEVICE;
3871 
3872  menu_items = gtk_check_menu_item_new_with_label("Ignore cursed");
3873  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3874  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3875  gtk_signal_connect(GTK_OBJECT(menu_items), "activate",
3876  GTK_SIGNAL_FUNC(new_menu_pickup), GINT_TO_POINTER(PU_NOT_CURSED));
3877  gtk_widget_show(menu_items);
3878  pickup_menus[pickup_count] = menu_items;
3879  pickup_value[pickup_count++] = PU_NOT_CURSED;
3880 
3881  menu_items = gtk_check_menu_item_new_with_label("Jewelry");
3882  gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(menu_items), TRUE);
3883  gtk_menu_append(GTK_MENU(newpickupmenu), menu_items);
3884  gtk_signal_connect(GTK_OBJECT(menu_items),"activate",
3885  GTK_SIGNAL_FUNC(new_menu_pickup),GINT_TO_POINTER(PU_JEWELS));
3886  gtk_widget_show(menu_items);
3887  pickup_menus[pickup_count] = menu_items;
3888  pickup_value[pickup_count++] = PU_JEWELS;
3889 /* --------------------------------------------------------------------- */
3890 /* --------------------------------------------------------------------- */
3891 /* --------------------------------------------------------------------- */
3892 /* --------------------------------------------------------------------- */
3893 /* --------------------------------------------------------------------- */
3894 
3895  /*Do the helpmenu */
3896  helpmenu = gtk_menu_new();
3897 
3898  menu_items = gtk_tearoff_menu_item_new ();
3899  gtk_menu_append (GTK_MENU (helpmenu), menu_items);
3900  gtk_widget_show (menu_items);
3901 
3902  menu_items = gtk_menu_item_new_with_label("Client commands");
3903  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3904  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3905  GTK_SIGNAL_FUNC(chelpdialog), NULL);
3906  gtk_widget_show(menu_items);
3907 
3908  menu_items = gtk_menu_item_new_with_label("Server help");
3909  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3910  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3911  GTK_SIGNAL_FUNC(shelpdialog), NULL);
3912  gtk_widget_show(menu_items);
3913 
3914  menu_items = gtk_menu_item_new ();
3915  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3916  gtk_widget_show(menu_items);
3917 
3918  /* Link to things like the client-walkthrough and the playbook? */
3919 
3920  menu_items = gtk_menu_item_new_with_label("Report a bug");
3921  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3922  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3923  GTK_SIGNAL_FUNC(bugdialog), NULL);
3924  gtk_widget_show(menu_items);
3925 
3926  menu_items = gtk_menu_item_new ();
3927  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3928  gtk_widget_show(menu_items);
3929 
3930 
3931  menu_items = gtk_menu_item_new_with_label("About");
3932  gtk_menu_append(GTK_MENU (helpmenu), menu_items);
3933  gtk_signal_connect_object(GTK_OBJECT(menu_items), "activate",
3934  GTK_SIGNAL_FUNC(aboutdialog), NULL);
3935  gtk_widget_show(menu_items);
3936 
3937  root_helpmenu = gtk_menu_item_new_with_label("Help");
3938 
3939  gtk_widget_show(root_helpmenu);
3940  gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_helpmenu), helpmenu);
3941 
3942  /* Create a menu-bar to hold the menus and add it to our main window */
3943 
3944 
3945  menu_bar = gtk_menu_bar_new();
3946  gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, 2);
3947  gtk_widget_show(menu_bar);
3948 
3949  /* Create a button to which to attach menu as a popup */
3950 
3951  /* And finally we append the menu-item to the menu-bar -- this is the
3952  * "root" menu-item I have been raving about =) */
3953  gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_filemenu);
3954  gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_clientmenu);
3955  gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_actionmenu);
3956  gtk_menu_item_right_justify (GTK_MENU_ITEM(root_helpmenu));
3957  gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), root_helpmenu);
3958 
3959  /* Always display the window as the last step so it all splashes on
3960  * the screen at once. */
3961 
3962  return 0;
3963 }
3964 
3965 
3966 
3967 /* get_root_display:
3968  * This sets up the root window (or none, if in split
3969  * windows mode, and also scans for any Xdefaults. Right now, only
3970  * splitwindow and image are used. image is the display
3971  * mechanism to use. I thought having one type that is set
3972  * to font, xpm, or pixmap was better than using xpm and pixmap
3973  * resources with on/off values (which gets pretty weird
3974  * if one of this is set to off.
3975  */
3976 
3977 
3978 /* Create the splash window at startup */
3979 
3980 static void create_splash(void) {
3981  GtkWidget *vbox;
3982  GtkWidget *aboutgtkpixmap;
3983  GdkPixmap *aboutgdkpixmap;
3984  GdkBitmap *aboutgdkmask;
3985  GtkStyle *style;
3986 
3987  gtkwin_splash = gtk_window_new (GTK_WINDOW_DIALOG);
3988  gtk_window_position (GTK_WINDOW (gtkwin_splash), GTK_WIN_POS_CENTER);
3989  gtk_widget_set_usize (gtkwin_splash,346,87);
3990  gtk_window_set_title (GTK_WINDOW (gtkwin_splash), "Welcome to Crossfire");
3991  gtk_signal_connect (GTK_OBJECT (gtkwin_splash), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_splash);
3992 
3993  gtk_container_border_width (GTK_CONTAINER (gtkwin_splash), 0);
3994  vbox = gtk_vbox_new(FALSE, 0);
3995  gtk_container_add (GTK_CONTAINER(gtkwin_splash),vbox);
3996  style = gtk_widget_get_style(gtkwin_splash);
3997  gtk_widget_realize(gtkwin_splash);
3998  aboutgdkpixmap = gdk_pixmap_create_from_xpm_d(gtkwin_splash->window,
3999  &aboutgdkmask,
4000  &style->bg[GTK_STATE_NORMAL],
4001  (gchar **)crossfiretitle_xpm);
4002  aboutgtkpixmap= gtk_pixmap_new (aboutgdkpixmap, aboutgdkmask);
4003  gtk_box_pack_start (GTK_BOX (vbox),aboutgtkpixmap, FALSE, TRUE, 0);
4004  gtk_widget_show (aboutgtkpixmap);
4005 
4006  gtk_widget_show (vbox);
4007  gtk_widget_show (gtkwin_splash);
4008 
4009 
4010  while ( gtk_events_pending() ) {
4011  gtk_main_iteration();
4012  }
4013  sleep (1);
4014  while ( gtk_events_pending() ) {
4015  gtk_main_iteration();
4016  }
4017 
4018 }
4019 
4020 
4021 static void destroy_splash(void) {
4022  gtk_widget_destroy(gtkwin_splash);
4023 }
4024 
4025 /* Error handlers removed. Right now, there is nothing for
4026  * the client to do if it gets a fatal error - it doesn't have
4027  * any information to save. And we might as well let the standard
4028  * X11 error handler handle non fatal errors.
4029  */
4030 
4031 
4032 void create_windows(void) {
4033  GtkWidget *rootvbox;
4034  GtkWidget *frame;
4035  int i;
4036 
4037  tooltips = gtk_tooltips_new();
4038 
4040  GtkStyle *style;
4041  int gcw;
4042  int gch;
4043  int rootwin_width;
4044  int rootwin_height;
4045 
4046  gtkwin_root = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4047  style = gtk_rc_get_style(gtkwin_root);
4048  if (style) {
4049 #ifdef CFGTK2 /* GTK 2.2 stuff */
4050  gcw = gdk_char_width(gdk_font_from_description(style->font_desc), '0') + 4;
4051  gch = gdk_char_height(gdk_font_from_description(style->font_desc), '0') + 2;
4052 #else
4053  gcw = gdk_char_width(style->font, '0') + 4;
4054  gch = gdk_char_height(style->font, '0') + 2;
4055 #endif
4056  } else {
4057  /* These are what the old defaults values were */
4058  gcw = 11;
4059  gch = 10;
4060  }
4061 
4062  gtk_widget_set_events (gtkwin_root, GDK_KEY_RELEASE_MASK);
4063  gtk_widget_set_uposition (gtkwin_root, 0, 0);
4064 
4065  if ((55*gcw)+(map_image_size*use_config[CONFIG_MAPWIDTH]) >= gdk_screen_width())
4066  rootwin_width = gdk_screen_width() - 30;
4067  else
4068  rootwin_width = (55*gcw)+(map_image_size*use_config[CONFIG_MAPWIDTH]);
4069  if ((33*gch)+(map_image_size*use_config[CONFIG_MAPHEIGHT]) >= gdk_screen_height())
4070  rootwin_height = gdk_screen_height() - 50;
4071  else
4072  rootwin_height = (33*gch)+(map_image_size*use_config[CONFIG_MAPHEIGHT]);
4073  gtk_widget_set_usize (gtkwin_root,rootwin_width,rootwin_height);
4074  gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire GTK Client");
4075  gtk_signal_connect_object(GTK_OBJECT(gtkwin_root), "destroy",GTK_SIGNAL_FUNC(main_window_destroyed), NULL);
4076 
4077  gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0);
4078 
4079  /* Alloc colors. colorname[] comes from xutil.c */
4080  for (i=0; i<=12; i++ ) {
4081  if ( !gdk_color_parse(colorname[i], &root_color[i])) {
4082  printf ("cparse failed (%s)\n",colorname[i]);
4083  }
4084  if ( !gdk_color_alloc (gtk_widget_get_colormap (gtkwin_root), &root_color[i])) {
4085  printf ("calloc failed\n");
4086  }
4087  }
4088 
4089  /* menu / windows division */
4090  rootvbox = gtk_vbox_new(FALSE, 0);
4091  gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox);
4092  gtk_widget_show (rootvbox);
4093 
4094  get_menu_display(rootvbox);
4095 
4096  /* first horizontal division. inv+obj on left, rest on right */
4097 
4098  inv_hpane = gtk_hpaned_new ();
4099 
4100  gtk_box_pack_start (GTK_BOX (rootvbox), inv_hpane, TRUE, TRUE, 0);
4101  gtk_container_border_width (GTK_CONTAINER(inv_hpane), 5);
4102  gtk_widget_show (inv_hpane);
4103 
4104  /* Divisior game+stats | text */
4105 
4106  stat_info_hpane = gtk_hpaned_new ();
4107  gtk_paned_add2 (GTK_PANED (inv_hpane), stat_info_hpane);
4108 
4109  /* text frame */
4110 
4111  frame = gtk_frame_new (NULL);
4112  gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
4113  gtk_widget_set_usize (frame, (25*gcw), (30*gch));
4114  gtk_paned_add2 (GTK_PANED (stat_info_hpane), frame);
4115 
4116  get_info_display (frame);
4117  gtk_widget_show (frame);
4118 
4119  /* game & statbars below, stats above */
4120  stat_game_vpane = gtk_vpaned_new ();
4121  gtk_paned_add1 (GTK_PANED (stat_info_hpane), stat_game_vpane);
4122 
4123 #if 0
4124  /* game - statbars */
4125  if (want_config[CONFIG_MAPWIDTH]>15) {
4126  bigmap=TRUE;
4127 
4128  game_bar_vpane = gtk_hpaned_new ();
4129  gtk_paned_add1 (GTK_PANED (stat_game_vpane), game_bar_vpane);
4130  } else {
4131  game_bar_vpane = gtk_vpaned_new ();
4132  gtk_paned_add2 (GTK_PANED (stat_game_vpane), game_bar_vpane);
4133  }
4134 #else
4135  game_bar_vpane = gtk_vpaned_new ();
4136  gtk_paned_add2 (GTK_PANED (stat_game_vpane), game_bar_vpane);
4137 #endif
4138 
4139 
4140  /* Statbars frame */
4141  message_frame = gtk_frame_new (NULL);
4142  gtk_frame_set_shadow_type (GTK_FRAME(message_frame), GTK_SHADOW_ETCHED_IN);
4143  gtk_widget_set_usize (message_frame, (22*gcw)+6, (map_image_size*use_config[CONFIG_MAPHEIGHT])+6);
4144  gtk_paned_add2 (GTK_PANED (game_bar_vpane), message_frame);
4145 
4147 
4148  gtk_widget_show (message_frame);
4149 
4150  /* Game frame */
4151  gameframe = gtk_frame_new (NULL);
4152  gtk_frame_set_shadow_type (GTK_FRAME(gameframe), GTK_SHADOW_ETCHED_IN);
4153  gtk_widget_set_usize (gameframe, (map_image_size*use_config[CONFIG_MAPWIDTH])+6, (map_image_size*use_config[CONFIG_MAPHEIGHT])+6);
4154 
4155  if (bigmap)
4156  gtk_paned_add2 (GTK_PANED (stat_game_vpane), gameframe);
4157  else
4158  gtk_paned_add1 (GTK_PANED (game_bar_vpane), gameframe);
4159 
4161 
4162  gtk_widget_show (gameframe);
4163 
4164  /* stats frame */
4165  stat_frame = gtk_frame_new (NULL);
4166  gtk_frame_set_shadow_type (GTK_FRAME(stat_frame), GTK_SHADOW_ETCHED_IN);
4167  if (bigmap)
4168  gtk_paned_add1 (GTK_PANED (game_bar_vpane), stat_frame);
4169  else
4170  gtk_paned_add1 (GTK_PANED (stat_game_vpane), stat_frame);
4171 
4173 
4174  gtk_widget_show (stat_frame);
4175 
4176  gtk_widget_show (game_bar_vpane);
4177  gtk_widget_show (stat_game_vpane);
4178 
4179  inv_look_vpane = gtk_vpaned_new ();
4180  gtk_paned_add1 (GTK_PANED (inv_hpane), inv_look_vpane);
4181 
4182  /* inventory frame */
4183  frame = gtk_frame_new (NULL);
4184  gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
4185  gtk_widget_set_usize (frame, (24*gcw), (33*gch));
4186  gtk_paned_add1 (GTK_PANED (inv_look_vpane), frame);
4187 
4188  get_inv_display (frame);
4189 
4190  gtk_widget_show (frame);
4191 
4192  /* look frame */
4193  frame = gtk_frame_new (NULL);
4194  gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
4195  gtk_widget_set_usize (frame, (24*gcw), (12*gch));
4196  gtk_paned_add2 (GTK_PANED (inv_look_vpane), frame);
4197 
4198  get_look_display (frame);
4199 
4200  gtk_widget_show (frame);
4201 
4202  gtk_widget_show (inv_look_vpane);
4203 
4204  gtk_widget_show (stat_info_hpane);
4205 
4206  gtk_widget_show (inv_hpane);
4207 
4208 
4209  /* Connect signals */
4210 
4211  gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event",
4212  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root));
4213  gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event",
4214  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root));
4215  gtk_widget_show (gtkwin_root);
4216 
4217 #ifdef HAVE_SDL
4219  init_SDL( drawingarea, 0);
4220 #endif
4221 
4222  } else { /* split window mode */
4223 
4224 
4225  /* game window */
4226 
4227  gtkwin_root = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4228  gtk_widget_set_events (gtkwin_root, GDK_KEY_RELEASE_MASK);
4229  gtk_widget_set_uposition (gtkwin_root, 300, 160);
4231  gtk_window_set_title (GTK_WINDOW (gtkwin_root), "Crossfire - view");
4232  gtk_window_set_policy (GTK_WINDOW (gtkwin_root), TRUE, TRUE, FALSE);
4233  gtk_signal_connect_object(GTK_OBJECT(gtkwin_root), "destroy",GTK_SIGNAL_FUNC(main_window_destroyed), NULL);
4234 
4235 
4236  gtk_container_border_width (GTK_CONTAINER (gtkwin_root), 0);
4237 
4238 
4239  rootvbox = gtk_vbox_new(FALSE, 0);
4240  gtk_container_add (GTK_CONTAINER (gtkwin_root), rootvbox);
4241 
4242  gtk_widget_realize (rootvbox);
4243 
4244  gtk_widget_realize (gtkwin_root);
4245 
4246 
4247 
4248  gtk_widget_show (rootvbox);
4249  gtk_widget_show (gtkwin_root);
4250  gtk_widget_draw (gtkwin_root,NULL);
4251  gtk_widget_draw (rootvbox,NULL);
4252 
4253  get_game_display(rootvbox);
4254 
4255 
4256 
4257  /* Stats and menu window */
4258  gtkwin_stats = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4259  gtk_widget_set_events (gtkwin_stats, GDK_KEY_RELEASE_MASK);
4260  gtk_widget_set_uposition (gtkwin_stats, 300, 0);
4261  gtk_widget_set_usize (gtkwin_stats,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,140);
4262  gtk_window_set_title (GTK_WINDOW (gtkwin_stats), "Crossfire GTK Client");
4263  gtk_window_set_policy (GTK_WINDOW (gtkwin_stats), TRUE, TRUE, FALSE);
4264  gtk_signal_connect (GTK_OBJECT (gtkwin_stats), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), &gtkwin_stats);
4265 
4266  gtk_container_border_width (GTK_CONTAINER (gtkwin_stats), 0);
4267 
4268 
4269  rootvbox = gtk_vbox_new(FALSE, 0);
4270  gtk_container_add (GTK_CONTAINER (gtkwin_stats), rootvbox);
4271  gtk_widget_show (rootvbox);
4272 
4273  get_menu_display(rootvbox);
4274  get_stats_display (rootvbox);
4275  gtk_widget_realize (gtkwin_stats);
4276  gdk_window_set_group (gtkwin_stats->window, gtkwin_root->window);
4277  gtk_widget_show (gtkwin_stats);
4278 
4279 
4280  /* info window - text and messages */
4281  gtkwin_info = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4282  gtk_widget_set_events (gtkwin_info, GDK_KEY_RELEASE_MASK);
4283  gtk_widget_set_uposition (gtkwin_info, 570, 0);
4284  gtk_widget_set_usize (gtkwin_info,400,600);
4285  gtk_window_set_title (GTK_WINDOW (gtkwin_info), "Crossfire - info");
4286  gtk_window_set_policy (GTK_WINDOW (gtkwin_info), TRUE, TRUE, FALSE);
4287  gtk_signal_connect (GTK_OBJECT (gtkwin_info), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), &gtkwin_info);
4288 
4289  gtk_container_border_width (GTK_CONTAINER (gtkwin_info), 0);
4290 
4291  /* Alloc colors - not entirely necessary, really, since GTK should do this */
4292  /* colorname[] comes from xutil.c */
4293  for (i=0; i<=12; i++ ) {
4294  if ( !gdk_color_parse(colorname[i], &root_color[i])) {
4295  printf ("cparse failed (%s)\n",colorname[i]);
4296  }
4297  if ( !gdk_color_alloc (gtk_widget_get_colormap (gtkwin_info), &root_color[i])) {
4298  printf ("calloc failed\n");
4299  }
4300  }
4301 
4302  rootvbox = gtk_vbox_new(FALSE, 0);
4303  gtk_container_add (GTK_CONTAINER (gtkwin_info), rootvbox);
4304  gtk_widget_show (rootvbox);
4305 
4306  get_info_display(rootvbox);
4307 
4308  gtk_widget_show (gtkwin_info);
4309  gtk_widget_realize (gtkwin_info);
4310  gdk_window_set_group (gtkwin_info->window, gtkwin_root->window);
4311 
4312  /* statbars window */
4313  gtkwin_message = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4314  gtk_widget_set_events (gtkwin_message, GDK_KEY_RELEASE_MASK);
4315  gtk_widget_set_uposition (gtkwin_message, 300, 450);
4316  gtk_widget_set_usize (gtkwin_message,(map_image_size*use_config[CONFIG_MAPWIDTH])+6,170);
4317  gtk_window_set_title (GTK_WINDOW (gtkwin_message), "Crossfire - vitals");
4318  gtk_window_set_policy (GTK_WINDOW (gtkwin_message), TRUE, TRUE, FALSE);
4319  gtk_signal_connect (GTK_OBJECT (gtkwin_message), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), &gtkwin_message);
4320 
4321  gtk_container_border_width (GTK_CONTAINER (gtkwin_message), 0);
4322 
4323 
4324  rootvbox = gtk_vbox_new(FALSE, 0);
4325  gtk_container_add (GTK_CONTAINER (gtkwin_message), rootvbox);
4326  gtk_widget_show (rootvbox);
4327 
4328  get_message_display(rootvbox);
4329 
4330  gtk_widget_show (gtkwin_message);
4331  gtk_widget_realize (gtkwin_message);
4332  gdk_window_set_group (gtkwin_message->window, gtkwin_root->window);
4333 
4334  /* inventory window */
4335  gtkwin_inv = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4336  gtk_widget_set_events (gtkwin_inv, GDK_KEY_RELEASE_MASK);
4337  gtk_widget_set_uposition (gtkwin_inv, 0, 0);
4338  gtk_widget_set_usize (gtkwin_inv,290,400);
4339  gtk_window_set_title (GTK_WINDOW (gtkwin_inv), "Crossfire - inventory");
4340  gtk_window_set_policy (GTK_WINDOW (gtkwin_inv), TRUE, TRUE, FALSE);
4341  gtk_signal_connect (GTK_OBJECT (gtkwin_inv), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), &gtkwin_inv);
4342 
4343  gtk_container_border_width (GTK_CONTAINER (gtkwin_inv), 0);
4344 
4345 
4346  rootvbox = gtk_vbox_new(FALSE, 0);
4347  gtk_container_add (GTK_CONTAINER (gtkwin_inv), rootvbox);
4348  gtk_widget_show (rootvbox);
4349 
4350  get_inv_display(rootvbox);
4351 
4352  gtk_widget_show (gtkwin_inv);
4353  gtk_widget_realize (gtkwin_inv);
4354  gdk_window_set_group (gtkwin_inv->window, gtkwin_root->window);
4355  /* look window */
4356  gtkwin_look = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4357  gtk_widget_set_events (gtkwin_look, GDK_KEY_RELEASE_MASK);
4358  gtk_widget_set_uposition (gtkwin_look, 0, 420);
4359  gtk_widget_set_usize (gtkwin_look,290,150);
4360  gtk_window_set_title (GTK_WINDOW (gtkwin_look), "Crossfire - look");
4361  gtk_window_set_policy (GTK_WINDOW (gtkwin_look), TRUE, TRUE, FALSE);
4362  gtk_signal_connect (GTK_OBJECT (gtkwin_look), "destroy", GTK_SIGNAL_FUNC(main_window_destroyed), &gtkwin_look);
4363 
4364  gtk_container_border_width (GTK_CONTAINER (gtkwin_look), 0);
4365 
4366 
4367  rootvbox = gtk_vbox_new(FALSE, 0);
4368  gtk_container_add (GTK_CONTAINER (gtkwin_look), rootvbox);
4369  gtk_widget_show (rootvbox);
4370 
4371  get_look_display(rootvbox);
4372 
4373  gtk_widget_show (gtkwin_look);
4374  gtk_widget_realize (gtkwin_look);
4375  gdk_window_set_group (gtkwin_look->window, gtkwin_root->window);
4376  /* Setup key events */
4377 
4378  gtk_signal_connect_object (GTK_OBJECT (gtkwin_message), "key_press_event",
4379  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_message));
4380  gtk_signal_connect_object (GTK_OBJECT (gtkwin_message), "key_release_event",
4381  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_message));
4382 
4383  gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_press_event",
4384  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_root));
4385  gtk_signal_connect_object (GTK_OBJECT (gtkwin_root), "key_release_event",
4386  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_root));
4387 
4388  gtk_signal_connect_object (GTK_OBJECT (gtkwin_info), "key_press_event",
4389  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_info));
4390  gtk_signal_connect_object (GTK_OBJECT (gtkwin_info), "key_release_event",
4391  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_info));
4392 
4393  gtk_signal_connect_object (GTK_OBJECT (gtkwin_look), "key_press_event",
4394  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_look));
4395  gtk_signal_connect_object (GTK_OBJECT (gtkwin_look), "key_release_event",
4396  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_look));
4397 
4398  gtk_signal_connect_object (GTK_OBJECT (gtkwin_inv), "key_press_event",
4399  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_inv));
4400  gtk_signal_connect_object (GTK_OBJECT (gtkwin_inv), "key_release_event",
4401  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_inv));
4402 
4403  gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_press_event",
4404  GTK_SIGNAL_FUNC(keyfunc), GTK_OBJECT(gtkwin_stats));
4405  gtk_signal_connect_object (GTK_OBJECT (gtkwin_stats), "key_release_event",
4406  GTK_SIGNAL_FUNC(keyrelfunc), GTK_OBJECT(gtkwin_stats));
4407 
4408 #ifdef HAVE_SDL
4410  init_SDL( drawingarea, 0);
4411 #endif
4412 
4413  } /* else split windows */
4414 
4415  /* load window positions from file */
4416  set_window_pos();
4417  gtk_tooltips_set_delay(tooltips, 1000 );
4418  if (use_config[CONFIG_TOOLTIPS]) {
4419  gtk_tooltips_enable(tooltips);
4420  }
4421 
4422 }
4423 
4424 static int get_root_display(char *display_name,int gargc, char **gargv) {
4425  gtk_init (&gargc,&gargv);
4426  last_str=malloc(32767);
4427 
4429  /* we need to call gdk_rgb_init very early on, as some of the
4430  * create window functions may do callbacks in which case we try
4431  * to draw the game window.
4432  */
4433  gdk_rgb_init();
4434  create_windows();
4435 
4436  return 0;
4437 }
4438 
4439 
4440 /* null procedures. gtk does this for us. */
4441 
4442 /* TODO Make these commands specific to x11 toolkit. */
4443 void set_scroll(const char *s)
4444 {
4445 }
4446 
4447 
4448 void set_autorepeat(const char *s) /* ...and what does this one *do*, anyway? */
4449 {
4450 }
4451 
4452 
4454 {
4455  /*
4456  * TODO Have crossfire-server send paragraphs rather than lines, so to
4457  * speak. Except for ASCII maps and things. Then this can go away
4458  * completely.
4459  */
4460  return 40;
4461 }
4462 
4463 
4464 
4465 /***********************************************************************
4466  *
4467  * Here is the start of event handling functions
4468  *
4469  ***********************************************************************/
4470 
4471 
4472 
4473 /* This function handles the reading of the X Events and then
4474  * doing the appropriate action. For most input events, it is calling
4475  * another function.
4476  *
4477  * It can also call display functions to make sure the information is
4478  * correct - in this way, updates will not be done so often (like
4479  * for every ITEM command received), but less frequently but still
4480  * update the display fully. All the functions above are optimized to
4481  * only draw stuff that needs drawing. So calling them a lot is not
4482  * going to draw stuff too much.
4483  */
4484 
4485 void do_clearlock(void) {
4486 }
4487 
4488 void x_set_echo(void) {
4489  gtk_entry_set_visibility(GTK_ENTRY(entrytext), !cpl.no_echo);
4490 }
4491 
4493  {
4494  if (draw_info_freeze1) {
4495  gtk_text_thaw (GTK_TEXT (gtkwin_info_text));
4496  gtk_adjustment_set_value(GTK_ADJUSTMENT(text_vadj), GTK_ADJUSTMENT(text_vadj)->upper-GTK_ADJUSTMENT(text_vadj)->page_size);
4497  gtk_text_set_adjustments(GTK_TEXT (gtkwin_info_text),GTK_ADJUSTMENT(text_hadj),GTK_ADJUSTMENT(text_vadj));
4499  }
4500  if (draw_info_freeze2) {
4501  gtk_text_thaw (GTK_TEXT (gtkwin_info_text2));
4502  gtk_adjustment_set_value(GTK_ADJUSTMENT(text_vadj2), GTK_ADJUSTMENT(text_vadj2)->upper-GTK_ADJUSTMENT(text_vadj2)->page_size);
4503  gtk_text_set_adjustments(GTK_TEXT (gtkwin_info_text2),GTK_ADJUSTMENT(text_hadj2),GTK_ADJUSTMENT(text_vadj2));
4505  }
4506  }
4507 
4508 
4509 /* X11 client doesn't care about this */
4511 {
4512  inventory_tick();
4514 #ifdef HAVE_SDL
4516  else
4517 #endif
4518  gtk_draw_map(0);
4519 }
4520 
4524 void client_pickup(uint32 pickup)
4525 {
4526  int menu;
4527 
4528  /* Update value, so handling function won't resend info. */
4529  pickup_mode = pickup;
4530 
4531  for (menu = 0; menu < pickup_count; menu++)
4532  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pickup_menus[menu]), (pickup & pickup_value[menu]) ? 1 : 0);
4533 }
4534 
4535 int do_timeout(void) {
4536 
4537  updatelock=0;
4538 
4539  if (!tick) {
4540  inventory_tick();
4542  }
4543  update_spell_list(0);
4545  if (redraw_needed) {
4548  }
4550  return TRUE;
4551 }
4552 
4553 int gtk_checkchilds(void) {
4554  monitorChilds();
4555  return FALSE;
4556 }
4557 
4558 
4559 
4560 /* Here are the old Xutil commands needed. */
4561 /* ----------------------------------------------------------------------------*/
4562 
4563 
4564 /* This function draws the magic map in the game window. I guess if
4565  * we wanted to get clever, we could open up some other window or
4566  * something.
4567  *
4568  * A lot of this code was taken from server/xio.c But being all
4569  * the map data has been figured, it tends to be much simpler.
4570  */
4571 void draw_magic_map(void)
4572 {
4573 
4574  int x=0;
4575  int y=0;
4576 
4577  GtkWidget *hbox;
4578  GtkWidget *closebutton;
4579  GtkStyle *style;
4580 
4581  static GtkWidget *magicgtkpixmap;
4582 
4583 
4584  static GdkBitmap *magicgdkmask;
4585 
4586 
4587  if (!cpl.magicmap) {
4588  draw_info ("You have yet to cast magic map.",NDI_BLACK);
4589  return;
4590  }
4591 
4592  if(!gtkwin_magicmap) {
4593 
4594  gtkwin_magicmap = gtk_window_new (GTK_WINDOW_DIALOG);
4595  gtk_window_position (GTK_WINDOW (gtkwin_magicmap), GTK_WIN_POS_CENTER);
4596  gtk_widget_set_usize (gtkwin_magicmap,264,300);
4597  gtk_window_set_title (GTK_WINDOW (gtkwin_magicmap), "Magic map");
4598  gtk_window_set_policy (GTK_WINDOW (gtkwin_magicmap), FALSE, FALSE, FALSE);
4599 
4600  gtk_signal_connect (GTK_OBJECT (gtkwin_magicmap), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_magicmap);
4601 
4602  mapvbox = gtk_vbox_new(FALSE, 0);
4603  gtk_widget_set_usize (mapvbox,264,300);
4604  gtk_container_add (GTK_CONTAINER(gtkwin_magicmap),mapvbox);
4605 
4606  style = gtk_widget_get_style(gtkwin_magicmap);
4607  gtk_widget_realize(mapvbox);
4608 
4609 
4610  magicgdkpixmap = gdk_pixmap_new(gtkwin_magicmap->window,
4611  264,
4612  264,
4613  -1);
4614  magicgtkpixmap= gtk_pixmap_new (magicgdkpixmap, magicgdkmask);
4615  gtk_box_pack_start (GTK_BOX (mapvbox),magicgtkpixmap, FALSE, FALSE, 0);
4616  gtk_widget_show (magicgtkpixmap);
4617 
4618  hbox = gtk_hbox_new(FALSE, 2);
4619 
4620  closebutton = gtk_button_new_with_label ("Close");
4621  gtk_signal_connect_object (GTK_OBJECT (closebutton), "clicked",
4622  GTK_SIGNAL_FUNC(gtk_widget_destroy),
4623  GTK_OBJECT (gtkwin_magicmap));
4624  gtk_box_pack_start (GTK_BOX (hbox), closebutton, TRUE, FALSE, 0);
4625  gtk_box_pack_start (GTK_BOX (mapvbox), hbox, FALSE, FALSE, 0);
4626  gtk_widget_show (closebutton);
4627  gtk_widget_show (hbox);
4628 
4629  gtk_widget_show (mapvbox);
4630  gtk_widget_show (gtkwin_magicmap);
4631 
4632 
4633  gdk_color_parse("Black", &map_color[0]);
4634  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[0]);
4635  gdk_color_parse("White", &map_color[1]);
4636  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[1]);
4637  gdk_color_parse("Navy", &map_color[2]);
4638  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[2]);
4639  gdk_color_parse("Red", &map_color[3]);
4640  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[3]);
4641  gdk_color_parse("Orange", &map_color[4]);
4642  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[4]);
4643  gdk_color_parse("DodgerBlue", &map_color[5]);
4644  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[5]);
4645  gdk_color_parse("DarkOrange2", &map_color[6]);
4646  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[6]);
4647  gdk_color_parse("SeaGreen", &map_color[7]);
4648  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[7]);
4649  gdk_color_parse("DarkSeaGreen", &map_color[8]);
4650  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[8]);
4651  gdk_color_parse("Grey50", &map_color[9]);
4652  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[9]);
4653  gdk_color_parse("Sienna", &map_color[10]);
4654  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[10]);
4655  gdk_color_parse("Gold", &map_color[11]);
4656  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[11]);
4657  gdk_color_parse("Khaki", &map_color[12]);
4658  gdk_color_alloc (gtk_widget_get_colormap (magicgtkpixmap), &map_color[12]);
4659 
4660 
4661  magic_map_gc = gdk_gc_new (magicgdkpixmap);
4662 
4663 
4664  gdk_gc_set_foreground (magic_map_gc, &map_color[0]);
4665  gdk_draw_rectangle (magicgdkpixmap, magic_map_gc,
4666  TRUE,
4667  0,
4668  0,
4669  264,
4670  264);
4671  cpl.mapxres = (262)/cpl.mmapx;
4672  cpl.mapyres = (262)/cpl.mmapy;
4673  if (cpl.mapxres < 1 || cpl.mapyres<1) {
4674  LOG(LOG_WARNING,"gtk::draw_magic_map","magic map resolution less than 1, map is %dx%d",
4675  cpl.mmapx, cpl.mmapy);
4676  return;
4677  }
4678  /* In theory, cpl.mapxres and cpl.mapyres do not have to be the same. However,
4679  * it probably makes sense to keep them the same value.
4680  * Need to take the smaller value.
4681  */
4683  else cpl.mapyres=cpl.mapxres;
4684 
4685  if (cpl.mapxres>24) {
4686  cpl.mapxres=24;
4687  cpl.mapyres=24;
4688  }
4689  /* This is keeping the same unpacking scheme that the server uses
4690  * to pack it up.
4691  */
4692  for (y = 0; y < cpl.mmapy; y++) {
4693  for (x = 0; x < cpl.mmapx; x++) {
4694  uint8 val = cpl.magicmap[y*cpl.mmapx + x];
4695 
4696  gdk_gc_set_foreground (magic_map_gc, &map_color[val&FACE_COLOR_MASK]);
4697 
4698  gdk_draw_rectangle (magicgdkpixmap, magic_map_gc,
4699  TRUE,
4700  2+cpl.mapxres*x,
4701  2+cpl.mapyres*y,
4702  cpl.mapxres,
4703  cpl.mapyres);
4704  } /* Saw into this space */
4705  }
4706  /* gdk_gc_destroy (magic_map_gc);*/
4707  gtk_widget_draw (mapvbox,NULL);
4708  }
4709 
4710  else {
4711  /* ------------------ There is already a magic map up - replace it ---------*/
4712 
4713  gdk_window_raise (gtkwin_magicmap->window);
4714  /* --------------------------- */
4715 
4716  gdk_gc_set_foreground (magic_map_gc, &map_color[0]);
4717  gdk_draw_rectangle (magicgdkpixmap, magic_map_gc,
4718  TRUE,
4719  0,
4720  0,
4721  264,
4722  264);
4723 
4724  cpl.mapxres = (262)/cpl.mmapx;
4725  cpl.mapyres = (262)/cpl.mmapy;
4726  if (cpl.mapxres < 1 || cpl.mapyres<1) {
4727  LOG(LOG_WARNING,"gtk::draw_magic_map","magic map resolution less than 1, map is %dx%d\n",
4728  cpl.mmapx, cpl.mmapy);
4729  return;
4730  }
4731 
4733  else cpl.mapyres=cpl.mapxres;
4734 
4735 
4736 
4737  if (cpl.mapxres>24) {
4738  cpl.mapxres=24;
4739  cpl.mapyres=24;
4740  }
4741 
4742 
4743 
4744  for (y = 0; y < cpl.mmapy; y++) {
4745  for (x = 0; x < cpl.mmapx; x++) {
4746  uint8 val = cpl.magicmap[y*cpl.mmapx + x];
4747 
4748  gdk_gc_set_foreground (magic_map_gc, &map_color[val&FACE_COLOR_MASK]);
4749 
4750  gdk_draw_rectangle (magicgdkpixmap, magic_map_gc,
4751  TRUE,
4752  2+cpl.mapxres*x,
4753  2+cpl.mapyres*y,
4754  cpl.mapxres,
4755  cpl.mapyres);
4756 
4757  }
4758 
4759  }
4760  gtk_widget_draw (mapvbox,NULL);
4761  }
4762 }
4763 
4764 /* Basically, this just flashes the player position on the magic map */
4765 
4767 {
4768  if (!cpl.showmagic) return;
4769  if (!gtkwin_magicmap) return;
4770  cpl.showmagic ^=2;
4771  if (cpl.showmagic & 2) {
4772  gdk_gc_set_foreground (magic_map_gc, &map_color[0]);
4773  } else {
4774  gdk_gc_set_foreground (magic_map_gc, &map_color[1]);
4775  }
4776  gdk_draw_rectangle (magicgdkpixmap, magic_map_gc,
4777  TRUE,
4778  2+cpl.mapxres*cpl.pmapx,
4779  2+cpl.mapyres*cpl.pmapy,
4780  cpl.mapxres,
4781  cpl.mapyres);
4782  gtk_widget_draw (mapvbox,NULL);
4783 }
4784 
4785 /* Gets a specified windows coordinates. This function is pretty much
4786  * an exact copy out of the server.
4787  */
4788 
4789 void get_window_coord(GtkWidget *win,
4790  int *x,int *y,
4791  int *wx,int *wy,
4792  int *w,int *h)
4793 {
4794  int tmp;
4795  gdk_window_get_geometry (win->window, x, y, w, h, &tmp);
4796 /* gdk_window_get_root_origin (win->window, wx, wy); */
4797 /* gdk_window_get_deskrelative_origin (win->window, wx, wy); */
4798  gdk_window_get_origin (win->window, wx, wy);
4799  *wx -= *x;
4800  *wy -= *y;
4801 }
4802 
4803 
4804 void save_winpos(void)
4805 {
4806  char savename[MAX_BUF],buf[MAX_BUF];
4807  FILE *fp;
4808  int x,y,w,h,wx,wy;
4809 
4811  sprintf(savename,"%s/.crossfire/gwinpos", getenv("HOME"));
4812  else
4813  sprintf(savename,"%s/.crossfire/winpos", getenv("HOME"));
4814 
4815  if (!(fp=fopen(savename,"w"))) {
4816  sprintf(buf,"Unable to open %s, window positions not saved",savename);
4817  draw_info(buf,NDI_BLUE);
4818  return;
4819  }
4820 
4821  get_window_coord(gtkwin_root, &x,&y, &wx,&wy,&w,&h);
4822  fprintf(fp,"win_game: %d %d %d %d\n", wx,wy, w, h);
4823  if (want_config[CONFIG_SPLITWIN]) {
4824  get_window_coord(gtkwin_stats, &x,&y, &wx,&wy,&w,&h);
4825  fprintf(fp,"win_stats: %d %d %d %d\n", wx,wy, w, h);
4826  get_window_coord(gtkwin_info, &x,&y, &wx,&wy,&w,&h);
4827  fprintf(fp,"win_info: %d %d %d %d\n", wx,wy, w, h);
4828  get_window_coord(gtkwin_inv, &x,&y, &wx,&wy,&w,&h);
4829  fprintf(fp,"win_inv: %d %d %d %d\n", wx,wy, w, h);
4830  get_window_coord(gtkwin_look, &x,&y, &wx,&wy,&w,&h);
4831  fprintf(fp,"win_look: %d %d %d %d\n", wx,wy, w, h);
4832  get_window_coord(gtkwin_message, &x,&y, &wx,&wy,&w,&h);
4833  fprintf(fp,"win_message: %d %d %d %d\n", wx,wy, w, h);
4834  } else {
4835  /* in non split mode, we really want the position of the
4836  * various panes. Current versions do not have a proper
4837  * way (ie, function call/macro) to do this - future
4838  * versions of gtk will have a gtk_paned_get_position.
4839  * That code basically does the same thing as what we
4840  * are doing below (version 1.3)
4841  */
4842  fprintf(fp,"inv_hpane: %d\n",
4843  GTK_PANED(inv_hpane)->child1_size);
4844  fprintf(fp,"stat_info_hpane: %d\n",
4845  GTK_PANED(stat_info_hpane)->child1_size);
4846  fprintf(fp,"stat_game_vpane: %d\n",
4847  GTK_PANED(stat_game_vpane)->child1_size);
4848  fprintf(fp,"game_bar_vpane: %d\n",
4849  GTK_PANED(game_bar_vpane)->child1_size);
4850  fprintf(fp,"inv_look_vpane: %d\n",
4851  GTK_PANED(inv_look_vpane)->child1_size);
4853  fprintf(fp,"info_vpane: %d\n",
4854  GTK_PANED(info_vpane)->child1_size);
4855  }
4856  fclose(fp);
4857  sprintf(buf,"Window positions saved to %s",savename);
4858  draw_info(buf,NDI_BLUE);
4859 }
4860 
4861 
4862 /* Reads in the winpos file created by the above function and sets the
4863  * the window positions appropriately.
4864  */
4865 void set_window_pos(void)
4866 {
4867  gint wx=0;
4868  gint wy=0;
4869  gint w=0;
4870  gint h=0;
4871 
4872  char buf[MAX_BUF],*cp;
4873  FILE *fp;
4874 
4876  sprintf(buf,"%s/.crossfire/winpos", getenv("HOME"));
4877  else
4878  sprintf(buf,"%s/.crossfire/gwinpos", getenv("HOME"));
4879 
4880  if (!(fp=fopen(buf,"r"))) return;
4881 
4882  while(fgets(buf,MAX_BUF-1, fp)!=NULL) {
4883  buf[MAX_BUF-1]='\0';
4884  if (!(cp=strchr(buf,' '))) continue;
4885  *cp++='\0';
4886  if (sscanf(cp,"%d %d %d %d",&wx,&wy,&w,&h)!=4) {
4887  gint pos = atoi(cp);
4888  if (pos == 0) continue;
4889 
4890  if (!strcmp(buf, "inv_hpane:")) gtk_paned_set_position(GTK_PANED(inv_hpane),pos);
4891  else if (!strcmp(buf, "stat_info_hpane:")) gtk_paned_set_position(GTK_PANED(stat_info_hpane),pos);
4892  else if (!strcmp(buf, "stat_game_vpane:")) gtk_paned_set_position(GTK_PANED(stat_game_vpane),pos);
4893  else if (!strcmp(buf, "game_bar_vpane:")) gtk_paned_set_position(GTK_PANED(game_bar_vpane),pos);
4894  else if (!strcmp(buf, "inv_look_vpane:")) gtk_paned_set_position(GTK_PANED(inv_look_vpane),pos);
4895  else if (use_config[CONFIG_SPLITINFO] && !strcmp(buf, "info_vpane:")) gtk_paned_set_position(GTK_PANED(info_vpane),pos);
4896  else LOG(LOG_ERROR,"gtk::set_window_pos","Found bogus line in window position file:\n/%s/ /%s/", buf, cp);
4897  } else {
4898  if (!strcmp(buf,"win_game:")) {
4899  gdk_window_move_resize(gtkwin_root->window, wx, wy, w, h);
4900  continue;
4901  }
4902  if (!want_config[CONFIG_SPLITWIN]) {
4903  LOG(LOG_ERROR,"gtk::set_window_pos","Found bogus line in window position file:\n%s %s", buf, cp);
4904  continue;
4905  }
4906  if (!strcmp(buf,"win_stats:")) {
4907  gdk_window_move_resize(gtkwin_stats->window, wx, wy, w, h);
4908  }
4909  if (!strcmp(buf,"win_info:")) {
4910  gdk_window_move_resize(gtkwin_info->window, wx, wy, w, h);
4911  }
4912  if (!strcmp(buf,"win_inv:")) {
4913  gdk_window_move_resize(gtkwin_inv->window, wx, wy, w, h);
4914  }
4915  if (!strcmp(buf,"win_look:")) {
4916  gdk_window_move_resize(gtkwin_look->window, wx, wy, w, h);
4917  }
4918  if (!strcmp(buf,"win_message:")) {
4919  gdk_window_move_resize(gtkwin_message->window, wx, wy, w, h);
4920  }
4921  } /* else if split windows */
4922  } /* while fgets */
4923  fclose(fp);
4924 }
4925 
4926 
4927 
4928 
4929 /***********************************************************************
4930  *
4931  * Here starts the X11 init functions. It will call other
4932  * functions that were grouped previously by window
4933  *
4934  ***********************************************************************/
4935 
4936 /* Usage routine. All clients should support server, port and
4937  * display options, with -pix and -xpm also suggested. -split
4938  * does not need to be supported - it is in this copy because
4939  * the old code supported it.
4940  */
4941 
4942 static void usage(const char *progname)
4943 {
4944  puts("Usage of crossfire-client-gtk:\n\n");
4945  puts("-cache - Cache images for future use.");
4946  puts("-nocache - Do not cache images (default action).");
4947  puts("-darkness - Enables darkness code (default)");
4948  puts("-nodarkness - Disables darkness code");
4949  puts("-display <name> - Use <name> instead if DISPLAY environment variable.");
4950  puts("-download_all_faces - Download all needed faces before play starts");
4951  puts("-echo - Echo the bound commands");
4952  puts("-noecho - Do not echo the bound commands (default)");
4953  puts("-faceset <name> - Use faceset <name> if available");
4954  puts("-fasttcpsend - Send data immediately to server, may increase bandwidth");
4955  puts("-nofasttcpsend - Disables fasttcpsend");
4956  puts("-fog - Enable fog of war code");
4957  puts("-help - Display this message.");
4958  puts("-loglevel <val> - Set default logging level (0 is most verbose)");
4959  puts("-iconscale %% - Set icon scale percentage");
4960  puts("-mapscale %% - Set map scale percentage");
4961  puts("-mapsize xXy - Set the mapsize to be X by Y spaces. (default 11x11)");
4962  puts("-splash - Display the splash screen (default)");
4963  puts("-nosplash - Don't display the splash screen (startup logo)");
4964  puts("-popups - Use pop up windows for input (default)");
4965  puts("-nopopups - Don't use pop up windows for input");
4966  puts("-port <number> - Use port <number> instead of the standard port number");
4967  puts("-sdl - Use sdl for drawing png (may not work on all hardware");
4968  puts("-server <name> - Connect to <name> instead of localhost.");
4969  puts("-showicon - Print status icons in inventory window");
4970  puts("-smooth - Enable smooth");
4971  puts("-nosmooth - Disable smooth");
4972  puts("-mapscroll - Enable mapscrolling by bitmap operations");
4973  puts("-nomapscroll - Disable mapscrolling by bitmap operations");
4974  puts("-sound - Enable sound output (default).");
4975  puts("-nosound - Disable sound output.");
4976  puts("-sound_server <path> - Executable to use to play sounds.");
4977  puts("-resists <val> - Control look of resistances.");
4978  puts("-split - Use split windows.");
4979  puts("-splitinfo - Use two information windows, segregated by information type.");
4980  puts("-timemapredraw - Print out timing information for map generation");
4981  puts("-triminfowindow - Trims size of information window(s)");
4982  puts("-notriminfowindow - Do not trims size of information window(s) (default)");
4983  puts("-updatekeycodes - Update the saved bindings for this keyboard.");
4984 
4985  exit(0);
4986 }
4987 
4988 /* init_windows: This initializes all the windows - it is an
4989  * interface routine. The command line arguments are passed to
4990  * this function to interpret. Note that it is not in fact
4991  * required to parse anything, but doing at least -server and
4992  * -port would be a good idea.
4993  *
4994  * This function returns 0 on success, nonzero on failure.
4995  */
4996 
4997 int init_windows(int argc, char **argv)
4998 {
4999  int on_arg=1;
5000  char *display_name="";
5001  load_defaults();
5002 
5003 #ifndef WIN32
5004  strcpy(VERSION_INFO,"GTK Unix Client " FULL_VERSION);
5005 #else
5006  strcpy(VERSION_INFO,"GTK Win32 Client " FULL_VERSION);
5007 #endif
5008  /* Set this global so we get skill experience - gtk client can display
5009  * it, so lets get the info.
5010  */
5011  want_skill_exp=1;
5012  for (on_arg=1; on_arg<argc; on_arg++) {
5013  if (!strcmp(argv[on_arg],"-cache")) {
5015  continue;
5016  }
5017  else if (!strcmp(argv[on_arg],"-nocache")) {
5019  continue;
5020  }
5021  else if (!strcmp(argv[on_arg],"-darkness")) {
5023  continue;
5024  }
5025  else if (!strcmp(argv[on_arg],"-nodarkness")) {
5027  continue;
5028  }
5029  else if (!strcmp(argv[on_arg],"-display")) {
5030  if (++on_arg == argc) {
5031  LOG(LOG_WARNING,"gtk::init_windows","-display requires a display name");
5032  return 1;
5033  }
5034  display_name = argv[on_arg];
5035  continue;
5036  }
5037  else if (!strcmp(argv[on_arg],"-download_all_faces")) {
5039  continue;
5040  }
5041  else if (!strcmp(argv[on_arg],"-echo")) {
5043  continue;
5044  }
5045  else if (!strcmp(argv[on_arg],"-noecho")) {
5047  continue;
5048  }
5049  else if (!strcmp(argv[on_arg],"-faceset")) {
5050  if (++on_arg == argc) {
5051  LOG(LOG_WARNING,"gtk::init_windows","-faceset requires a faceset name/number");
5052  return 1;
5053  }
5054  face_info.want_faceset = argv[on_arg];
5055  continue;
5056  }
5057  else if( !strcmp( argv[on_arg],"-fog")) {
5059  continue;
5060  }
5061  else if( !strcmp( argv[on_arg],"-nofog")) {
5063  continue;
5064  }
5065  else if (!strcmp(argv[on_arg],"-help")) {
5066  usage(argv[0]);
5067  continue;
5068  }
5069  else if( !strcmp( argv[on_arg],"-iconscale")) {
5070  if (++on_arg == argc) {
5071  LOG(LOG_WARNING,"gtk::init_windows","-iconscale requires a percentage value");
5072  return 1;
5073  }
5074  want_config[CONFIG_ICONSCALE] = atoi(argv[on_arg]);
5076  LOG(LOG_WARNING,"gtk::init_windows","Valid range for -iconscale is 25 through 200");
5078  return 1;
5079  }
5080  continue;
5081  }
5082  else if( !strcmp( argv[on_arg],"-mapscale")) {
5083  if (++on_arg == argc) {
5084  LOG(LOG_WARNING,"gtk::init_windows","-mapscale requires a percentage value");
5085  return 1;
5086  }
5087  want_config[CONFIG_MAPSCALE] = atoi(argv[on_arg]);
5089  LOG(LOG_WARNING,"gtk::init_windows","Valid range for -mapscale is 25 through 200");
5091  return 1;
5092  }
5093  continue;
5094  }
5095  else if (!strcmp(argv[on_arg],"-mapsize")) {
5096  char *cp, x, y=0;
5097  if (++on_arg == argc) {
5098  LOG(LOG_WARNING,"gtk::init_windows","-mapsize requires a XxY value");
5099  return 1;
5100  }
5101  x = atoi(argv[on_arg]);
5102  for (cp = argv[on_arg]; *cp!='\0'; cp++)
5103  if (*cp == 'x' || *cp == 'X') break;
5104 
5105  if (*cp==0) {
5106  LOG(LOG_WARNING,"gtk::init_windows","-mapsize requires both and X and Y value (ie, XxY - note the\nx in between.");
5107  } else {
5108  y = atoi(cp+1);
5109  }
5110  if (x<9 || y<9) {
5111  LOG(LOG_WARNING,"gtk::init_windows","map size must be positive values of at least 9");
5112  } else if (x>MAP_MAX_SIZE || y>MAP_MAX_SIZE) {
5113  LOG(LOG_WARNING,"gtk::init_windows","Map size can not be larger than %d x %d", MAP_MAX_SIZE, MAP_MAX_SIZE);
5114 
5115  } else {
5118  }
5119  continue;
5120  }
5121  else if (!strcmp(argv[on_arg],"-fasttcpsend")) {
5123  continue;
5124  }
5125  else if (!strcmp(argv[on_arg],"-nofasttcpsend")) {
5127  continue;
5128  }
5129  else if (!strcmp(argv[on_arg],"-popups")) {
5131  continue;
5132  }
5133  else if (!strcmp(argv[on_arg],"-nopopups")) {
5135  continue;
5136  }
5137  else if (!strcmp(argv[on_arg],"-port")) {
5138  if (++on_arg == argc) {
5139  LOG(LOG_WARNING,"gtk::init_windows","-port requires a port number");
5140  return 1;
5141  }
5142  want_config[CONFIG_PORT] = atoi(argv[on_arg]);
5143  continue;
5144  }
5145  else if (!strcmp(argv[on_arg],"-sdl")) {
5146 #ifndef HAVE_SDL
5147  LOG(LOG_WARNING,"gtk::init_windows","client not compiled with sdl support. Ignoring -sdl");
5148 #else
5150 #endif
5151  continue;
5152  }
5153  else if (!strcmp(argv[on_arg],"+sdl")) {
5155  continue;
5156  }
5157  else if (!strcmp(argv[on_arg],"-server")) {
5158  if (++on_arg == argc) {
5159  LOG(LOG_WARNING,"gtk::init_windows","-server requires a host name");
5160  return 1;
5161  }
5162  server = argv[on_arg];
5163  continue;
5164  }
5165  else if (!strcmp(argv[on_arg],"-showicon")) {
5167  continue;
5168  }
5169  else if (!strcmp(argv[on_arg],"-smooth")) {
5171  }
5172  else if (!strcmp(argv[on_arg],"-nosmooth")) {
5174  }
5175  else if (!strcmp(argv[on_arg],"-mapscroll")) {
5177  }
5178  else if (!strcmp(argv[on_arg],"-nomapscroll")) {
5180  }
5181  else if (!strcmp(argv[on_arg],"-sound")) {
5183  continue;
5184  }
5185  else if (!strcmp(argv[on_arg],"-nosound")) {
5187  continue;
5188  }
5189  else if (!strcmp(argv[on_arg],"-sound_server")) {
5190  if (++on_arg == argc) {
5191  LOG(LOG_WARNING,"gtk::init_windows","-sound_server requires an executable pathname");
5192  return 1;
5193  }
5194  sound_server = argv[on_arg];
5195  continue;
5196  }
5197  else if (!strcmp(argv[on_arg],"-split")) {
5199  continue;
5200  }
5201  else if (!strcmp(argv[on_arg],"-nosplit")) {
5203  continue;
5204  }
5205  else if (!strcmp(argv[on_arg],"-resists")) {
5206  if (++on_arg == argc) {
5207  LOG(LOG_WARNING,"gtk::init_windows","-resists requires a value");
5208  return 1;
5209  }
5210  want_config[CONFIG_RESISTS]=atoi(argv[on_arg]);
5211  continue;
5212  }
5213  else if (!strcmp(argv[on_arg],"-loglevel")) {
5214  extern int MINLOG;
5215 
5216  if (++on_arg == argc) {
5217  LOG(LOG_WARNING,"gtk::init_windows","-loglevel requires a value");
5218  return 1;
5219  }
5220  MINLOG = atoi(argv[on_arg]);
5221  continue;
5222  }
5223  else if (!strcmp(argv[on_arg],"-splitinfo")) {
5225  continue;
5226  }
5227  else if (!strcmp(argv[on_arg],"-timemapredraw")) {
5229  continue;
5230  }
5231  else if (!strcmp(argv[on_arg],"-triminfowindow")) {
5233  continue;
5234  }
5235  else if (!strcmp(argv[on_arg],"-notriminfowindow")) {
5237  continue;
5238  }
5239  else if (!strcmp(argv[on_arg],"-updatekeycodes")) {
5241  continue;
5242  }
5243  else if (!strcmp(argv[on_arg],"-splash")) {
5245  continue;
5246  }
5247  else if (!strcmp(argv[on_arg],"-nosplash")) {
5249  continue;
5250  }
5251  else {
5252  LOG(LOG_WARNING,"gtk::init_windows","Do not understand option %s", argv[on_arg]);
5253  usage(argv[0]);
5254  return 1;
5255  }
5256  }
5257 
5258  LOG(LOG_INFO,"Client Version",VERSION_INFO);
5259 
5260  /* Now copy over the values just loaded */
5261  for (on_arg=0; on_arg<CONFIG_NUMS; on_arg++) {
5262  use_config[on_arg] = want_config[on_arg];
5263  }
5264 
5270 
5271  mapdata_init();
5272 
5273  /* Finished parsing all the command line options. Now start
5274  * working on the display.
5275  */
5276  gargc=argc;
5277  gargv=argv;
5278 
5279  for (on_arg = 0; on_arg<MAX_HISTORY; on_arg++)
5280  history[on_arg][0]=0;
5281 
5282 
5283  if (get_root_display(display_name,gargc,gargv))
5284  return 1;
5285 
5286  init_keys();
5287  init_cache_data();
5289  gtk_timeout_add (10,(GtkFunction)gtk_checkchilds,NULL);
5290  return 0;
5291 }
5292 
5293 
5300 void display_map_doneupdate(int redraw, int notice)
5301 {
5302  if (notice)
5303  return;
5304 
5305  if (updatelock < 30) {
5306  updatelock++;
5307 
5308 #ifdef HAVE_SDL
5310  else
5311 #endif
5312  gtk_draw_map(redraw);
5313  } /* if updatelock */
5314  else {
5315  redraw_needed = TRUE;
5316  }
5317 }
5318 
5320 {
5321  reset_map();
5322 }
5323 
5324 void resize_map_window(int x, int y)
5325 {
5326  gtk_drawing_area_size(GTK_DRAWING_AREA(drawingarea), map_image_size * x, map_image_size * y);
5327  if (!want_config[CONFIG_SPLITWIN]) {
5328 #if 0
5329  /* 15 it is a purely arbitary value. But basically, if the map window is
5330  * narrow, we then will have the stats on top, with message down below
5331  * the map window. IF the map window is wide, we put these side
5332  * by side at the top
5333  */
5334  if (bigmap && x<15) {
5335 
5336  /* reverse of below basically. */
5337  GtkWidget *newpane; /* will take place of game_bar_vpane */
5338 
5339  bigmap =FALSE;
5340 
5341  newpane = gtk_vpaned_new(); /*game in pane1, bars in pane2 */
5342 
5343  /* Remove referance to the split - the stats frame takes its place */
5344  gtk_widget_ref(game_bar_vpane);
5345  gtk_container_remove(GTK_CONTAINER(stat_game_vpane), game_bar_vpane);
5346 
5347  /* Stat now gets the entire top pane to itself */
5348  gtk_widget_ref(stat_frame);
5349  gtk_container_remove(GTK_CONTAINER(game_bar_vpane), stat_frame);
5350  gtk_paned_add1(GTK_PANED(stat_game_vpane), stat_frame);
5351  gtk_widget_unref(stat_frame);
5352 
5353  /* statbars now second part of bottom frame */
5354  gtk_widget_ref(message_frame);
5355  gtk_container_remove(GTK_CONTAINER(game_bar_vpane), message_frame);
5356  gtk_paned_add2(GTK_PANED(newpane), message_frame);
5357  gtk_widget_unref(message_frame);
5358 
5359  /* game now first part of bottom frame */
5360  gtk_widget_ref(gameframe);
5361  gtk_container_remove(GTK_CONTAINER(stat_game_vpane), gameframe);
5362  gtk_paned_add1(GTK_PANED(newpane), gameframe);
5363  gtk_widget_unref(gameframe);
5364 
5365  gtk_paned_add2(GTK_PANED(stat_game_vpane), newpane);
5366 
5367  gtk_widget_show(newpane);
5368  /* This should also destroy it */
5369  gtk_widget_unref(game_bar_vpane);
5370  game_bar_vpane = newpane;
5371 
5372  } else if (!bigmap && x>=15) {
5373 
5374  GtkWidget *newpane; /* will take place of game_bar_vpane */
5375  bigmap=TRUE;
5376  newpane = gtk_hpaned_new();
5377 
5378  /* We need to remove this here - the game pane is goind to
5379  * take game_bar_vpane as second position in the stat_game_vpane.
5380  * add a refcount so it isn't destroyed.
5381  */
5382  gtk_widget_ref(game_bar_vpane);
5383  gtk_container_remove(GTK_CONTAINER(stat_game_vpane), game_bar_vpane);
5384 
5385 
5386  /* Stat and message are now split on 'newpane' */
5387  gtk_widget_ref(stat_frame);
5388  gtk_container_remove(GTK_CONTAINER(stat_game_vpane), stat_frame);
5389  gtk_paned_add1(GTK_PANED(newpane), stat_frame);
5390  gtk_widget_unref(stat_frame);
5391 
5392  gtk_widget_ref(message_frame);
5393  gtk_container_remove(GTK_CONTAINER(game_bar_vpane), message_frame);
5394  gtk_paned_add2(GTK_PANED(newpane), message_frame);
5395  gtk_widget_unref(message_frame);
5396 
5397  /* the game is now part 2 of stat_game_vpane, and not part of
5398  * game_bar_vpane
5399  */
5400 
5401  gtk_widget_ref(gameframe);
5402  gtk_container_remove(GTK_CONTAINER(game_bar_vpane), gameframe);
5403  gtk_paned_add2(GTK_PANED(stat_game_vpane), gameframe);
5404  gtk_widget_unref(gameframe);
5405 
5406  /* Newpane (split stat/message) is now part one of stat_game_vpane */
5407  gtk_paned_add1(GTK_PANED(stat_game_vpane), newpane);
5408 
5409  gtk_widget_show(newpane);
5410  /* This should also destroy it */
5411  gtk_widget_unref(game_bar_vpane);
5412  game_bar_vpane = newpane;
5413  }
5414 #endif
5416  } else {
5418  }
5419 
5420 #ifdef HAVE_SDL
5423 #endif
5424 
5425 }
5426 
5427 
5429 {
5430 }
5431 
5432 char *get_metaserver(void)
5433 {
5435 
5436 
5438  /*
5439  * This gtk_main will be quit inside of event_callback
5440  * when the user enters data into the input_text box
5441  * at which point the input_state will change.
5442  */
5443  gtk_main();
5444  usleep(10*1000); /* 10 milliseconds */
5445  }
5446  return cpl.input_text;
5447 }
5448 /*default log window to 200 lines of about 50 characters*/
5449 #define MAX_LOG_CHARACTERS 10000
5451  if (bugtrack){
5452  gtk_text_freeze (GTK_TEXT (bugtrack));
5453  gtk_text_insert (GTK_TEXT (bugtrack), NULL, &bugtrack->style->black,NULL, getLogText(le), -1);
5454  printf ("current gtk len: %d\n",gtk_text_get_length(GTK_TEXT (bugtrack)));
5455  if (gtk_text_get_length(GTK_TEXT (bugtrack)) > MAX_LOG_CHARACTERS){
5456  /*gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), TRUE);*/
5457  guint toomuch =gtk_text_get_length(GTK_TEXT (bugtrack))-MAX_LOG_CHARACTERS;
5458  printf("Deleteing..%d\n",toomuch);
5459  gtk_text_set_point(GTK_TEXT (bugtrack),toomuch);
5460  gtk_text_backward_delete(GTK_TEXT (bugtrack),toomuch);
5461  gtk_text_set_point(GTK_TEXT (bugtrack),gtk_text_get_length(GTK_TEXT (bugtrack)));
5462  /* gtk_text_set_editable (GTK_TEXT (gtkwin_info_text), FALSE);*/
5463  }
5464  gtk_text_thaw (GTK_TEXT (bugtrack));
5465  }
5466 }
5467 #define MAX_RECURSE 50
5468 /* a handler for the glib error logging. Used so we care ourself of the gtk/gdk warnings
5469  * and make them appear in message window using the logging facility
5470  */
5471 void gLogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data){
5472  static char LogOrigin[4096];
5473  static int recurse = 0;
5474  LogLevel level;
5475  gboolean in_recursion;
5476  gboolean is_fatal;
5477  /*printf ("hi i received a g error on %s with severity %d and message %s\n",log_domain,log_level,message);*/
5478  if (recurse > MAX_RECURSE)
5479  return; /*don't Log*/
5480  if (recurse == MAX_RECURSE){
5481  recurse++;
5482  LOG(LOG_ERROR,"gtk::gLogHandler","Too many recurse, reached limit: %d",recurse);
5483  recurse--;
5484  return;
5485  }
5486  LogOrigin[0]='\0';
5487  strcat (LogOrigin,"Library::");
5488  in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
5489  is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
5490  log_level &= G_LOG_LEVEL_MASK;
5491 
5492  if (!message)
5493  message = "gLogHandler: (NULL) message";
5494  if (log_domain){
5495  strcat(LogOrigin,log_domain);
5496  strcat(LogOrigin,"-");
5497  }else
5498  strcat(LogOrigin, "** ");
5499 
5500 
5501  switch (log_level)
5502  {
5503  case G_LOG_LEVEL_ERROR:/*Our critical*/
5504  strcat (LogOrigin,"ERROR");
5505  level=LOG_CRITICAL;
5506  break;
5507  case G_LOG_LEVEL_CRITICAL:/*our error*/
5508  strcat (LogOrigin,"CRITICAL");
5509  level=LOG_ERROR;
5510  break;
5511  case G_LOG_LEVEL_WARNING:/*our warning*/
5512  strcat (LogOrigin,"WARNING");
5513  level=LOG_WARNING;
5514  break;
5515  case G_LOG_LEVEL_MESSAGE:/* message */
5516  strcat (LogOrigin,"Message");
5517  level=LOG_INFO;
5518  break;
5519  case G_LOG_LEVEL_INFO:/* message */
5520  strcat (LogOrigin,"Info");
5521  level=LOG_INFO;
5522  break;
5523  case G_LOG_LEVEL_DEBUG:/*our debug*/
5524  strcat (LogOrigin,"DEBUG");
5525  level=LOG_DEBUG;
5526  break;
5527  default:
5528  strcat (LogOrigin,"LOG");
5529  level=LOG_WARNING;
5530  break;
5531  }
5532  if (in_recursion)
5533  strcat(LogOrigin," (recursed)");
5534  /*else
5535  strcat(LogOrigin,"**: ");*/
5536  recurse++;
5537  LOG(level,LogOrigin,"%s",message);
5538  if (is_fatal)
5539  LOG(level,LogOrigin,"Last Message was fatal, aborting...");
5540  recurse--;
5541 }
5542 
5543 
5544 extern const char* cached_server_file;
5545 
5546 int main(int argc, char *argv[])
5547 {
5548  int got_one=0;
5549  static char file_cache[ MAX_BUF ];
5550 
5551  g_log_set_handler (NULL,G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR|
5552  G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|
5553  G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL);
5554  g_log_set_handler ("Gtk",G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR|
5555  G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|
5556  G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL);
5557  g_log_set_handler ("Gdk",G_LOG_FLAG_RECURSION|G_LOG_FLAG_FATAL|G_LOG_LEVEL_ERROR|
5558  G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING |G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_INFO|
5559  G_LOG_LEVEL_DEBUG,(GLogFunc)gLogHandler,NULL);
5560 
5561  /* This needs to be done first. In addition to being quite quick,
5562  * it also sets up some paths (client_libdir) that are needed by
5563  * the other functions.
5564  */
5565  init_client_vars();
5566 
5567  /* Override ../common/init.c default for POPUPS for this client only
5568  * because when compiled with --enable-cfgtk2, a player is not able to
5569  * login to the server if POPUPS are disabled. See bug # 2022488 at
5570  * http://sourceforge.net/tracker/index.php?func=detail&aid=2022488&group_id=13833&atid=113833
5571  */
5573 
5574 
5575  snprintf( file_cache, MAX_BUF, "%s/.crossfire/servers.cache", getenv( "HOME" ) );
5576  cached_server_file = file_cache;
5579  /* Call this very early. It should parse all command
5580  * line arguments and set the pertinent ones up in
5581  * globals. Also call it early so that if it can't set up
5582  * the windowing system, we get an error before trying to
5583  * to connect to the server. And command line options will
5584  * likely change on the server we connect to.
5585  */
5586  if (init_windows(argc, argv)) { /* x11.c */
5587  LOG(LOG_CRITICAL,"gtk::main","Failure to init windows.");
5588  exit(1);
5589  }
5590 
5591  csocket.inbuf.buf=malloc(MAXSOCKBUF);
5592 
5593 #ifdef WIN32 /* def WIN32 */
5594  maxfd = 0; /* This is ignored on win32 platforms */
5595 
5596  /* This is required for sockets to be used under win32 */
5597  {
5598  WORD Version = 0x0202;
5599  WSADATA wsaData;
5600  if (WSAStartup( Version, &wsaData ) != 0) {
5601  LOG(LOG_CRITICAL,"gtk::main", "Couldn't load winsock!");
5602  exit(1);
5603  }
5604  }
5605 #else /* def WIN32 */
5606 #ifdef HAVE_SYSCONF
5607  maxfd = sysconf(_SC_OPEN_MAX);
5608 #else
5609  maxfd = getdtablesize();
5610 #endif
5611 #endif /* def WIN32 */
5612 
5613  if (init_sounds() == -1)
5615  else use_config[CONFIG_SOUND] = TRUE;
5616 
5617  /* Loop to connect to server/metaserver and play the game */
5618  while (1) {
5620  csocket.inbuf.len=0;
5621  csocket.cs_version=0;
5622 
5623  /* Perhaps not the best assumption, but we are taking it that
5624  * if the player has not specified a server (ie, server
5625  * matches compiled in default), we use the metaserver.
5626  * otherwise, use the server provided, bypassing metaserver.
5627  * Also, if the player has already played on a server once (defined
5628  * by got_one), go to the metaserver. That gives them the opportunity
5629  * to quit the client or select another server. We should really add
5630  * an entry for the last server there also.
5631  */
5632 
5633  if (!server || got_one) {
5634  char *ms;
5637  do {
5639  ms=get_metaserver();
5640  } while (metaserver_select(ms));
5642  } else {
5644  if (csocket.fd == -1) { /* specified server no longer valid */
5645  server = NULL;
5646  continue;
5647  }
5649  }
5650 
5651  got_one=1;
5652  event_loop();
5653  /* if event_loop has exited, we most of lost our connection, so we
5654  * loop again to establish a new one.
5655  */
5656 
5657  mapdata_reset();
5658  /* Need to reset the images so they match up properly and prevent
5659  * memory leaks.
5660  */
5661  reset_image_data();
5665  }
5666  exit(0); /* never reached */
5667 }
GtkWidget * level
Definition: gx11.c:165
uint16 pmapx
Definition: client.h:297
static gboolean info_text_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
Definition: gx11.c:828
#define NDI_ORANGE
Definition: newclient.h:205
void negotiate_connection(int sound)
Definition: client.c:338
static char history[MAX_HISTORY][MAX_COMMAND_LEN]
Definition: gx11.c:190
static GtkWidget * list
Definition: gx11.c:2982
#define PU_KEY
Definition: gx11.c:144
static GtkWidget * gtkwin_shelp
Definition: gx11.c:287
static GtkWidget * stat_info_hpane
Definition: gx11.c:298
#define PU_HELMET
Definition: gx11.c:137
uint32 spells_updated
Definition: client.h:289
#define PU_SPELLBOOK
Definition: gx11.c:151
signed short sint16
Definition: client-types.h:80
static int get_info_display(GtkWidget *frame)
Definition: gx11.c:867
static GdkColor map_color[16]
Definition: gx11.c:242
static XFontStruct * font
Definition: x11.c:192
GdkColor gdk_green
Definition: gx11.c:237
#define PU_POTION
Definition: gx11.c:149
static int height
Definition: mapdata.c:104
struct news_entry * next
Definition: gx11.h:107
static void menu_disarm(void)
Definition: gx11.c:2941
static void usage(const char *progname)
Definition: gx11.c:4942
sint8 level
Definition: client.h:215
news_entry * get_news(void)
Definition: text.c:462
void init_SDL(GtkWidget *sdl_window, int just_lightmap)
struct FaceCache facecache[MAXPIXMAPNUM]
static void shelpdialog(GtkWidget *widget)
Definition: gx11.c:2790
int can_write_spell_on(item *it)
Definition: item.c:752
GtkWidget * playername
Definition: gx11.c:163
void move_player(int dir)
Definition: player.c:99
#define PU_INHIBIT
Definition: gx11.c:125
uint16 grace
Definition: client.h:260
static GtkWidget * info_vpane
Definition: gx11.c:298
#define PU_MISSILEWEAPON
Definition: gx11.c:146
sint32 face
Definition: client.h:268
GtkTooltips * tooltips
Definition: gx11.c:252
sint16 hp
Definition: client.h:216
#define DEFAULT_IMAGE_SIZE
Definition: gx11.c:114
GtkWidget * dam
Definition: gx11.c:177
void mapdata_animation(void)
Definition: mapdata.c:1264
static GtkWidget * bugtrack
Definition: gx11.c:290
GtkWidget * gtkwin_info
Definition: gx11.c:278
static GtkObject * text_vadj2
Definition: gx11.c:272
void init_client_vars(void)
Definition: init.c:97
sint8 Int
Definition: client.h:211
void monitorChilds(void)
Definition: misc.c:239
static GdkGC * magic_map_gc
Definition: gx11.c:246
sint32 speed
Definition: client.h:229
static GtkWidget * loginMessage
Definition: gx11.c:1025
#define CONFIG_POPUPS
Definition: client.h:160
static void menu_apply(void)
Definition: gx11.c:2928
static void init_cache_data(void)
Definition: gx11.c:504
static void create_stat_bar(GtkWidget *mtable, gint row, const gchar *label, gint bar, GtkWidget **plabel)
Definition: gx11.c:2235
void configdialog(GtkWidget *widget)
Definition: config.c:379
static XEvent event
Definition: x11.c:193
void clear_fire(void)
Definition: player.c:134
#define CONFIG_ECHO
Definition: client.h:153
void do_clearlock(void)
Definition: gx11.c:4485
sint8 Str
Definition: client.h:206
static GtkWidget * inv_hpane
Definition: gx11.c:298
void draw_info_windows(void)
Definition: gx11.c:4492
void gtkLogListener(LogEntry *le)
Definition: gx11.c:5450
int init_windows(int argc, char **argv)
Definition: gx11.c:4997
#define PU_DEBUG
Definition: gx11.c:124
#define MAX_SKILL
Definition: client.h:61
static void menu_pickup5(void)
Definition: gx11.c:2901
item * ob
Definition: client.h:272
static void cancelConnection(GtkButton *button, gpointer func_data)
Definition: gx11.c:1056
sint16 food
Definition: client.h:223
uint16 icon_height
Definition: gx11.h:62
void keyfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
Definition: keys.c:1008
static int info2_num_chars
Definition: gx11.c:209
#define MAP_MAX_SIZE
Definition: client.h:447
#define CONFIG_TIMESTAMP
Definition: client.h:182
void metaserver_show(int show_selection)
Definition: metaserver.c:807
#define MAX_RECURSE
Definition: gx11.c:5467
#define FACE_COLOR_MASK
Definition: newclient.h:251
static void sendPassword(void)
Definition: gx11.c:1283
int metaserver_select(char *sel)
Definition: metaserver.c:861
void display_map_doneupdate(int redraw, int notice)
Definition: gx11.c:5300
uint8 * magicmap
Definition: client.h:299
int total
Definition: gx11.c:322
struct item_struct * next
Definition: item.h:46
ClientSocket csocket
Definition: client.c:78
sint16 maxhp
Definition: client.h:217
static gboolean draw_info_freeze1
Definition: gx11.c:261
static GtkWidget * rulesText
Definition: gx11.c:1020
GtkWidget * bar
Definition: gx11.c:222
void mapdata_reset(void)
Definition: mapdata.c:572
static GtkObject * text_vadj
Definition: gx11.c:271
#define PU_SKILLSCROLL
Definition: gx11.c:152
static void new_menu_pickup(GtkWidget *button, int val)
Definition: gx11.c:2847
Face_Information face_info
Definition: image.c:167
sint8 ac
Definition: client.h:214
static void create_splash(void)
Definition: gx11.c:3980
uint32 repelled
Definition: client.h:236
int map_image_half_size
Definition: gx11.c:117
#define CONFIG_SPLASH
Definition: client.h:178
void * fog_image
Definition: gx11.h:65
int command_inscribe
Definition: client.c:75
Stats stats
Definition: client.h:285
#define MAXPIXMAPNUM
Definition: client.h:470
#define CONFIG_FOGWAR
Definition: client.h:157
sint16 want_config[CONFIG_NUMS]
Definition: init.c:50
int y
Definition: gx11.c:215
GtkWidget * ckeyentrytext
Definition: gx11.c:235
#define NDI_GREEN
Definition: newclient.h:208
#define CONFIG_MAPSCALE
Definition: client.h:159
void inventory_tick(void)
Definition: inventory.c:1374
void gtk_draw_map(int redraw)
Definition: map.c:337
int meta_port
Definition: client.c:67
LogLevel
Definition: client.h:367
uint32 resist_change
Definition: client.h:242
const char *const resists_name[NUM_RESISTS]
Definition: client.c:80
uint32 no_echo
Definition: client.h:294
static void buildLoginDialog(void)
Definition: gx11.c:1109
GtkWidget * armor
Definition: gx11.c:179
sint64 skill_exp[MAX_SKILL]
Definition: client.h:244
sint8 Con
Definition: client.h:208
static void bugdialog(GtkWidget *widget)
Definition: gx11.c:2655
sint8 Cha
Definition: client.h:210
int setLogListener(LogListener li)
Definition: misc.c:137
static GtkWidget * resists[NUM_RESISTS]
Definition: gx11.c:234
void set_scroll(const char *s)
Definition: gx11.c:4443
uint16 pmapy
Definition: client.h:297
#define MAX_HISTORY
Definition: gx11.c:188
uint8 redraw_needed
Definition: gx11.c:205
#define CONFIG_SPLITINFO
Definition: client.h:165
static int pickup_count
Definition: gx11.c:3280
char * server
Definition: client.c:56
uint16 map_height
Definition: gx11.h:64
GtkWidget * speed
Definition: gx11.c:180
GtkWidget * closebutton
Definition: inventory.c:1015
static void confirmUserPass(GtkButton *button, gpointer func_data)
Definition: gx11.c:1048
int maxfd
Definition: client.c:68
static GtkWidget * gtkwin_splash
Definition: gx11.c:286
uint32 tag
Definition: client.h:255
char * skill_names[MAX_SKILL]
Definition: client.c:63
static void do_network(void)
Definition: gx11.c:339
#define PU_BOW
Definition: gx11.c:134
static void select_spell_event(GtkWidget *gtklist, gint row, gint column, GdkEventButton *event)
Definition: gx11.c:3003
void client_tick(uint32 tick)
Definition: gx11.c:4510
PixmapInfo * pixmaps[MAXPIXMAPNUM]
Definition: gx11.c:118
static void setUserPass(GtkButton *button, gpointer func_data)
Definition: gx11.c:1028
GtkWidget * Pow
Definition: gx11.c:175
Definition: gx11.h:104
#define PU_READABLES
Definition: gx11.c:153
uint16 icon_width
Definition: gx11.h:62
int init_sounds(void)
Definition: sound.c:60
static GtkWidget * gtkwin_magicmap
Definition: gx11.c:288
static GtkWidget * spelloptions
Definition: gx11.c:2983
int updatelock
Definition: gx11.c:310
static gint csocket_fd
Definition: gx11.c:195
static GtkWidget * dialogtext
Definition: gx11.c:254
GdkPixmap * mapwindow
Definition: gx11.c:248
sint8 Pow
Definition: client.h:212
char * name
Definition: gx11.c:318
static void event_loop(void)
Definition: gx11.c:394
static void click_inscribe_spell(void)
Definition: gx11.c:2987
char * get_metaserver(void)
Definition: gx11.c:5432
static Stats last_stats
Definition: x11.c:264
static StatWindow statwindow
Definition: gx11.c:275
static void menu_pickup7(void)
Definition: gx11.c:2912
GtkWidget * gtkwin_info_text
Definition: gx11.c:279
void * map_image
Definition: gx11.h:63
#define PU_FLESH
Definition: gx11.c:158
int init_connection(char *host, int port)
Definition: client.c:205
#define CFG_DM_SDL
Definition: client.h:195
void draw_stats(int redraw)
Definition: gx11.c:2015
int x
Definition: gx11.c:214
GdkColor gdk_grey
Definition: gx11.c:239
uint32 denied
Definition: client.h:239
uint16 num
Definition: gx11.c:319
GtkWidget * sp
Definition: gx11.c:167
static int width
Definition: mapdata.c:104
static int info1_num_chars
Definition: gx11.c:209
void LOG(LogLevel level, const char *origin, const char *format,...)
Definition: misc.c:178
uint8 updatekeycodes
Definition: gx11.c:204
static int pickup_value[43]
Definition: gx11.c:3279
void reset_client_vars(void)
Definition: init.c:249
static void draw_stat_bar(int bar_pos, float bar, int is_alert)
Definition: gx11.c:2403
char * content
Definition: gx11.h:106
static GtkWidget * newsText
Definition: gx11.c:1021
#define NDI_RED
Definition: newclient.h:204
static void menu_pickup0(void)
Definition: gx11.c:2876
void gtk_command_history(int direction)
Definition: gx11.c:558
void draw_prompt(const char *str)
Definition: gx11.c:1310
static unsigned int pmode
Definition: pickup.c:99
#define TRUE
Definition: client-types.h:71
void reset_image_data(void)
Definition: image.c:387
static void sexit(void)
Definition: gx11.c:3264
void draw_color_info(int colr, const char *buf)
Definition: gx11.c:1851
uint32 tick
Definition: client.c:70
gchar * text
Definition: about.h:2
void look_at(int x, int y)
Definition: player.c:75
static void fill_news(GtkWidget *o, news_entry *news)
Definition: gx11.c:1093
static void menu_pickup10(void)
Definition: gx11.c:2917
GtkWidget * Dex
Definition: gx11.c:170
sint16 grace
Definition: client.h:220
GdkPixmap * dark
Definition: gx11.c:250
#define PU_MAGIC_DEVICE
Definition: gx11.c:154
GdkColor gdk_black
Definition: gx11.c:240
#define NUM_RESISTS
Definition: client.h:432
int gtk_checkchilds(void)
Definition: gx11.c:4553
char * servername
Definition: client.h:106
#define CONFIG_FOODBEEP
Definition: client.h:172
static void menu_search(void)
Definition: gx11.c:2937
sint16 resists[30]
Definition: client.h:241
static void menu_who(void)
Definition: gx11.c:2924
static GtkWidget * loginTabs
Definition: gx11.c:1022
int map_image_size
Definition: gx11.c:117
GtkWidget * Con
Definition: gx11.c:171
#define CONFIG_NUMS
Definition: client.h:183
#define PU_DRINK
Definition: gx11.c:132
static GtkObject * text_hadj2
Definition: gx11.c:272
void client_pickup(uint32 pickup)
Definition: gx11.c:4524
#define CONFIG_PORT
Definition: client.h:174
char * title
Definition: gx11.h:105
GtkWidget * cclist
Definition: gx11.c:260
static GtkWidget * loginWindow
Definition: gx11.c:1018
Definition: gx11.c:221
static void menu_pickup1(void)
Definition: gx11.c:2881
const char * getMOTD(void)
Definition: text.c:454
sint8 Dex
Definition: client.h:207
static void confirmPassword(void)
Definition: gx11.c:1287
int send_command(const char *command, int repeat, int must_send)
Definition: player.c:195
GtkWidget * Wis
Definition: gx11.c:173
sint16 use_config[CONFIG_NUMS]
Definition: init.c:50
void * map_mask
Definition: gx11.h:63
char d_name[NAME_LEN]
Definition: item.h:50
void * icon_image
Definition: gx11.h:61
item * below
Definition: client.h:273
void reset_map(void)
Definition: map.c:76
char * getLogText(const LogEntry *le)
Definition: misc.c:164
Client_Player cpl
Definition: client.c:77
uint16 flags
Definition: client.h:240
static GtkWidget * gtkwin_about
Definition: gx11.c:284
#define PU_STOP
Definition: gx11.c:126
static GtkWidget * motdText
Definition: gx11.c:1019
static uint8 bigmap
Definition: gx11.c:200
static void menu_spells(void)
Definition: gx11.c:3088
#define CONFIG_GRAD_COLOR
Definition: client.h:175
int misses
Definition: gx11.c:322
static void enter_callback(GtkWidget *widget, GtkWidget *entry)
Definition: gx11.c:779
uint16 mapxres
Definition: client.h:302
static void disable_ok_if_empty(gpointer button, GtkEditable *entry)
Definition: gx11.c:1062
GtkWidget * gtkwin_root
Definition: gx11.c:278
GtkWidget * Cha
Definition: gx11.c:174
static GtkWidget * dialog_window
Definition: gx11.c:255
#define CONFIG_CACHE
Definition: client.h:156
static GtkWidget * stat_game_vpane
Definition: gx11.c:298
void mapdata_init(void)
Definition: mapdata.c:514
#define CONFIG_MAPSCROLL
Definition: client.h:180
static GtkWidget * skill_scrolled_window
Definition: gx11.c:231
#define CONFIG_FASTTCP
Definition: client.h:154
int fd
Definition: client.h:97
void inscribe_magical_scroll(item *scroll, Spell *spell)
Definition: item.c:756
char message[10000]
Definition: client.h:253
void reset_stat_bars(void)
Definition: gx11.c:2264
void draw_info(const char *str, int color)
Definition: gx11.c:1773
char name[40]
Definition: client.h:306
static GtkWidget * gtkwin_spell
Definition: gx11.c:2980
void cclist_button_event(GtkWidget *gtklist, gint row, gint column, GdkEventButton *event)
Definition: gx11.c:2758
void set_look_list_env(item *op)
Definition: inventory.c:1323
GtkWidget * cnumentrytext
Definition: gx11.c:235
int do_timeout(void)
Definition: gx11.c:4535
static int scroll_history_position
Definition: gx11.c:191
unsigned short uint16
Definition: client-types.h:79
void extended_command(const char *ocommand)
Definition: p_cmd.c:890
GtkWidget * gtkwin_look
Definition: gx11.c:281
GtkWidget * entrytext
Definition: gx11.c:270
GtkWidget * ckentrytext
Definition: gx11.c:235
uint16 mmapy
Definition: client.h:296
GdkGC * mapgc
Definition: gx11.c:258
void create_windows(void)
Definition: gx11.c:4032
void chelpdialog(GtkWidget *widget)
Definition: help.c:182
int state
Definition: gx11.c:224
void send_reply(const char *text)
Definition: commands.c:769
static void destroy_splash(void)
Definition: gx11.c:4021
static GtkWidget * description
Definition: gx11.c:2981
sint16 maxgrace
Definition: client.h:221
LogEntry * LogFirst
Definition: misc.c:133
#define NDI_GREY
Definition: newclient.h:211
int main(int argc, char *argv[])
Definition: gx11.c:5546
int get_info_width(void)
Definition: gx11.c:4453
static void menu_pickup6(void)
Definition: gx11.c:2907
GdkColor gdk_red
Definition: gx11.c:238
void display_map_newmap(void)
Definition: gx11.c:5319
static const char *const colorname[]
Definition: gx11.c:98
#define NDI_WHITE
Definition: newclient.h:202
static void activate_ok_if_not_empty(GtkWidget *button, GtkEditable *entry)
Definition: gx11.c:1086
const char * complete_command(const char *command)
Definition: p_cmd.c:972
#define CONFIG_SMOOTH
Definition: client.h:177
#define PU_SHIELD
Definition: gx11.c:138
struct Spell_struct * next
Definition: client.h:249
GtkWidget * drawingarea
Definition: gx11.c:256
void x_set_echo(void)
Definition: gx11.c:4488
static int cur_history_position
Definition: gx11.c:191
sint16 maxsp
Definition: client.h:219
static void createBugTracker(void)
Definition: gx11.c:2642
void main_window_destroyed(void)
Definition: config.c:219
static void menu_pickup3(void)
Definition: gx11.c:2891
void client_exit(void)
Definition: gx11.c:3269
GdkColor root_color[16]
Definition: gx11.c:244
uint16 dam
Definition: client.h:261
#define MAX_BUF
Definition: client-types.h:128
#define CFG_DM_PIXMAP
Definition: client.h:194
GdkBitmap * dark2
Definition: gx11.c:249
#define MAX_TIME
Definition: cconfig.h:39
GtkWidget * hp
Definition: gx11.c:166
GtkWidget * gtkwin_message
Definition: gx11.c:281
void save_defaults(void)
Definition: config.c:848
#define PU_MAGICAL
Definition: gx11.c:148
static unsigned int pickup_mode
Definition: gx11.c:308
sint16 dam
Definition: client.h:226
static int info1_max_chars
Definition: gx11.c:209
static int get_stats_display(GtkWidget *frame)
Definition: gx11.c:1861
void gLogHandler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition: gx11.c:5471
void get_window_coord(GtkWidget *win, int *x, int *y, int *wx, int *wy, int *w, int *h)
Definition: gx11.c:4789
static char ** gargv
Definition: gx11.c:186
static gint dialog_delete_event_callback(GtkWidget *widget, GdkEvent *event, gpointer data)
Definition: gx11.c:1104
Spell * spelldata
Definition: client.h:286
unsigned int uint32
Definition: client-types.h:77
GdkBitmap * dark3
Definition: gx11.c:249
#define CONFIG_MAPWIDTH
Definition: client.h:170
#define CONFIG_SHOWICON
Definition: client.h:162
static Vitals vitals[4]
Definition: gx11.c:227
unsigned char * buf
Definition: newclient.h:573
int len
Definition: newclient.h:572
char name[256]
Definition: client.h:250
void draw_message_window(int redraw)
Definition: gx11.c:2458
void get_inv_display(GtkWidget *frame)
Definition: inventory.c:1084
#define CONFIG_TRIMINFO
Definition: client.h:169
GtkWidget * spellinventory
Definition: gx11.c:2984
char * sound_server
Definition: client.c:62
sint32 weapon_sp
Definition: client.h:230
GtkWidget * food
Definition: gx11.c:181
GdkBitmap * dark1
Definition: gx11.c:249
static int get_root_display(char *display_name, int gargc, char **gargv)
Definition: gx11.c:4424
#define CONFIG_ICONSCALE
Definition: client.h:158
static void change_focus(GtkWidget *focusTo, GtkEditable *entry)
Definition: gx11.c:1079
#define PU_ALLWEAPON
Definition: gx11.c:147
static void aboutdialog(GtkWidget *widget)
Definition: gx11.c:2568
static void dialog_callback(GtkWidget *dialog)
Definition: gx11.c:1007
static void update_spell_list(int force)
Definition: gx11.c:3033
uint8 showmagic
Definition: client.h:300
GtkWidget * gtkwin_stats
Definition: gx11.c:281
#define MAXSOCKBUF
Definition: newclient.h:79
void cleanup_connection(void)
Definition: gx11.c:329
GtkWidget * skill_exp[MAX_SKILL *2]
Definition: gx11.c:183
static int info2_max_chars
Definition: gx11.c:210
void script_fdset(int *maxfd, fd_set *set)
Definition: script.c:559
void remove_item_inventory(item *op)
Definition: item.c:382
void resize_map_window(int x, int y)
Definition: gx11.c:5324
#define CONFIG_MAPHEIGHT
Definition: client.h:171
void draw_magic_map(void)
Definition: gx11.c:4571
GtkWidget * score
Definition: gx11.c:164
uint32 attuned
Definition: client.h:233
#define CONFIG_DOWNLOAD
Definition: client.h:152
sint16 sp
Definition: client.h:218
static GtkWidget * restable
Definition: gx11.c:229
itemlist inv_list
Definition: inventory.c:1013
#define CONFIG_RESISTS
Definition: client.h:176
#define PU_BOOTS
Definition: gx11.c:141
void set_window_pos(void)
Definition: gx11.c:4865
uint16 sp
Definition: client.h:259
void magic_map_flash_pos(void)
Definition: gx11.c:4766
void get_look_display(GtkWidget *frame)
Definition: inventory.c:1021
int want_skill_exp
Definition: client.c:67
static GtkWidget * pickup_menus[43]
Definition: gx11.c:3278
void display_map_startupdate(void)
Definition: gx11.c:5428
SockList inbuf
Definition: client.h:98
Pixmap pixmap
Definition: xutil.c:67
static int gargc
Definition: gx11.c:197
static GtkWidget * passwordText2
Definition: gx11.c:1017
void set_autorepeat(const char *s)
Definition: gx11.c:4448
static GtkWidget * res_scrolled_window
Definition: gx11.c:230
uint16 level
Definition: client.h:257
static GtkWidget * mapvbox
Definition: gx11.c:247
#define PU_NEWMODE
Definition: gx11.c:127
Input_State input_state
Definition: client.h:277
char range[MAX_BUF]
Definition: client.h:288
uint16 mapyres
Definition: client.h:302
void init_common_cache_data(void)
Definition: image.c:332
GtkStyle * style[2]
Definition: gx11.c:223
const char *const rcsid_gtk_gx11_c
Definition: gx11.c:1
void DoClient(ClientSocket *csocket)
Definition: client.c:149
#define PU_ARMOUR
Definition: gx11.c:139
guint signalLoginDialogClicked
Definition: gx11.c:1261
const char * cached_server_file
Definition: metaserver.c:107
char title[MAX_BUF]
Definition: client.h:287
uint16 smooth_face
Definition: gx11.h:66
void load_defaults(void)
Definition: config.c:710
int metaserver_get_info(char *metaserver, int meta_port)
Definition: metaserver.c:791
char VERSION_INFO[256]
Definition: client.c:59
#define PU_GLOVES
Definition: gx11.c:142
#define PU_VALUABLES
Definition: gx11.c:133
char input_text[MAX_BUF]
Definition: client.h:279
#define CONFIG_DISPLAYMODE
Definition: client.h:161
static GtkWidget * loginButtonOk
Definition: gx11.c:1023
static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
Definition: gx11.c:707
static char * last_str
Definition: gx11.c:305
void resize_resistance_table(int resists_show)
Definition: gx11.c:2350
media_state write_media(GtkText *textarea, const char *message)
Definition: text.c:282
GtkWidget * gr
Definition: gx11.c:168
unsigned char uint8
Definition: client-types.h:81
Definition: gx11.c:213
static GtkWidget * passwordText
Definition: gx11.c:1016
#define FULL_VERSION
Definition: version.h:6
GtkWidget * wc
Definition: gx11.c:176
char password[64]
Definition: gx11.c:1027
static GtkObject * text_hadj
Definition: gx11.c:271
GtkWidget * run_label
Definition: gx11.c:228
struct timeval timeout
Definition: gx11.c:194
static void button_map_event(GtkWidget *widget, GdkEventButton *event)
Definition: gx11.c:436
void gtk_complete_command(void)
Definition: gx11.c:587
uint16 mmapx
Definition: client.h:296
static GdkPixmap * magicgdkpixmap
Definition: gx11.c:245
sint8 wc
Definition: client.h:213
char * meta_server
Definition: client.c:61
#define NDI_BLACK
Definition: newclient.h:201
int MINLOG
Definition: misc.c:174
struct item_struct * inv
Definition: item.h:49
sint16 skill_level[MAX_SKILL]
Definition: client.h:243
GtkWidget * cmodentrytext
Definition: gx11.c:235
static GtkWidget * gtkwin_bug
Definition: gx11.c:285
uint8 time_map_redraw
Definition: gx11.c:203
#define FALSE
Definition: client-types.h:68
sint8 Wis
Definition: client.h:209
static void logUserIn(void)
Definition: gx11.c:1262
struct LogEntry * next
Definition: client.h:375
void cleanup_textmanagers(void)
Definition: text.c:522
static void menu_pickup2(void)
Definition: gx11.c:2886
#define FLOAT_MULTF
Definition: newclient.h:102
sint64 exp
Definition: client.h:222
GtkWidget * Str
Definition: gx11.c:169
int image_size
Definition: gx11.c:116
#define PU_JEWELS
Definition: gx11.c:157
static int get_menu_display(GtkWidget *box)
Definition: gx11.c:3286
static GtkWidget * message_frame
Definition: gx11.c:273
void save_winpos(void)
Definition: gx11.c:4804
uint32 path
Definition: client.h:266
void init_text_callbacks(void)
Definition: text.c:515
#define CONFIG_SPLITWIN
Definition: client.h:166
void script_process(fd_set *set)
Definition: script.c:572
#define PU_NOT_CURSED
Definition: gx11.c:156
GtkWidget * fire_label
Definition: gx11.c:228
media_state write_media_with_state(GtkText *textarea, const char *message, media_state current_state)
Definition: text.c:289
GtkWidget * ac
Definition: gx11.c:178
static GtkWidget * inv_look_vpane
Definition: gx11.c:298
#define CONFIG_DARKNESS
Definition: client.h:173
#define PU_CLOAK
Definition: gx11.c:143
void disconnect(GtkWidget *widget)
Definition: gx11.c:2773
static int get_game_display(GtkWidget *frame)
Definition: gx11.c:725
void itemlist_set_show_icon(itemlist *l, int new_setting)
Definition: inventory.c:1288
static GtkWidget * stat_frame
Definition: gx11.c:273
sint16 face
Definition: item.h:57
#define PU_ARROW
Definition: gx11.c:136
#define CONFIG_TOOLTIPS
Definition: client.h:163
GtkWidget * Int
Definition: gx11.c:172
void sdl_gen_map(int redraw)
void menu_clear(void)
Definition: gx11.c:3241
static GtkWidget * userText
Definition: gx11.c:1015
void fire_dir(int dir)
Definition: player.c:151
static GtkWidget * gameframe
Definition: gx11.c:273
static void menu_cast(void)
Definition: gx11.c:2932
#define MAX_COMMAND_LEN
Definition: gx11.c:189
#define MAX_LOG_CHARACTERS
Definition: gx11.c:5449
static GtkWidget * loginButtonCancel
Definition: gx11.c:1024
static GtkWidget * game_bar_vpane
Definition: gx11.c:298
GtkWidget * gtkwin_info_text2
Definition: gx11.c:280
GtkWidget * gtkwin_inv
Definition: gx11.c:281
void keyrelfunc(GtkWidget *widget, GdkEventKey *event, GtkWidget *window)
Definition: keys.c:994
#define NDI_BLUE
Definition: newclient.h:206
#define CONFIG_SOUND
Definition: client.h:164
#define PU_FOOD
Definition: gx11.c:131
static gint configure_event(GtkWidget *widget, GdkEventConfigure *event)
Definition: gx11.c:612
static void menu_pickup4(void)
Definition: gx11.c:2896
GtkWidget * skill
Definition: gx11.c:182
static void spellinventory_redraw(GtkWidget *list, GdkEventVisibility *event, gpointer view_x)
Definition: gx11.c:2945
static gboolean draw_info_freeze2
Definition: gx11.c:261
static int get_message_display(GtkWidget *frame)
Definition: gx11.c:2282
void init_keys(void)
Definition: keys.c:302
char * skill
Definition: client.h:264
uint16 map_width
Definition: gx11.h:64
int cs_version
Definition: client.h:99
const char * get_rules(void)
Definition: text.c:459
static void sendstr(char *sendstr)
Definition: gx11.c:992
void * icon_mask
Definition: gx11.h:61