1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2018 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <sys/types.h>
45 attributes (const char *filename
, int line
, char *str
)
50 while ((tmp
= strsep (&str
, ",")) != NULL
)
52 if (strcasecmp (tmp
, "BOLD") == 0)
54 else if (strcasecmp (tmp
, "REVERSE") == 0)
56 else if (strcasecmp (tmp
, "NONE") == 0)
58 else if (strcasecmp (tmp
, "DIM") == 0)
60 else if (strcasecmp (tmp
, "STANDOUT") == 0)
62 else if (strcasecmp (tmp
, "UNDERLINE") == 0)
64 else if (strcasecmp (tmp
, "BLINK") == 0)
66 else if (strcasecmp (tmp
, "INVISIBLE") == 0)
69 errx (EXIT_FAILURE
, _("%s(%i): invalid attribute \"%s\""), filename
,
77 color_name (const char *filename
, int line
, const char *color
)
79 if (strcasecmp (color
, "BLACK") == 0)
81 else if (strcasecmp (color
, "WHITE") == 0)
83 else if (strcasecmp (color
, "GREEN") == 0)
85 else if (strcasecmp (color
, "YELLOW") == 0)
87 else if (strcasecmp (color
, "MAGENTA") == 0)
89 else if (strcasecmp (color
, "BLUE") == 0)
91 else if (strcasecmp (color
, "RED") == 0)
93 else if (strcasecmp (color
, "CYAN") == 0)
95 else if (strcasecmp (color
, "-") == 0)
98 errx (EXIT_FAILURE
, _("%s(%i): invalid color \"%s\""), filename
, line
,
105 parse_color (const char *filename
, int line
, const char *str
,
108 char fg
[16], bg
[16], attr
[64], nattr
[64];
112 sscanf (str
, "%[a-zA-Z-] %[a-zA-Z-] %[a-zA-Z,-] %[a-zA-Z,-]", fg
, bg
,
114 errx (EXIT_FAILURE
, _("%s(%i): parse error"), filename
, line
);
116 if ((n
= color_name (filename
, line
, fg
)) >= 0)
119 if ((n
= color_name (filename
, line
, bg
)) >= 0)
122 c
->attrs
= c
->nattrs
= 0;
125 c
->attrs
= attributes (filename
, line
, attr
);
128 c
->nattrs
= attributes (filename
, line
, nattr
);
132 on_or_off (const char *filename
, int lines
, const char *str
)
134 if (strcasecmp (str
, "on") == 0 || strcasecmp (str
, "1") == 0 ||
135 strcasecmp (str
, "yes") == 0 || strcasecmp (str
, "true") == 0)
138 if (strcasecmp (str
, "off") == 0 || strcasecmp (str
, "0") == 0 ||
139 strcasecmp (str
, "no") == 0 || strcasecmp (str
, "false") == 0)
142 errx (EXIT_FAILURE
, _("%s(%i): invalid value \"%s\""), filename
, lines
,
147 copydatafile (const char *dst
, const char *src
)
150 char buf
[LINE_MAX
], *s
;
152 snprintf (buf
, sizeof (buf
), "%s/%s", DATA_PATH
, src
);
154 if ((fp
= fopen (buf
, "r")) == NULL
)
161 if ((ofp
= fopen (dst
, "w+")) == NULL
)
168 while ((s
= fgets (buf
, sizeof (buf
), fp
)) != NULL
)
169 fprintf (ofp
, "%s", s
);
176 fancy_key_name (wint_t c
)
178 static char buf
[64] = { 0 };
181 strncpy (buf
, keyname (c
) ? keyname (c
) : key_name (c
), sizeof (buf
) - 1);
184 if (*p
== '^' && *(p
+ 1) == '[')
187 if (*p
== '^' && *(p
+ 1) == 'J')
190 if (strncasecmp (p
, "KEY_", 4) == 0)
192 for (p
= buf
; *p
; p
++)
210 else if (strcmp (p
, "ppage") == 0)
212 else if (strcmp (p
, "npage") == 0)
226 add_key_binding (struct key_s
***dst
, key_func
* func
, wint_t c
,
227 char *desc
, int repeat
)
230 struct key_s
**k
= *dst
;
233 for (i
= 0; k
[i
]; i
++);
235 k
= Realloc (k
, (i
+ 2) * sizeof (struct key_s
*));
236 k
[i
] = Calloc (1, sizeof (struct key_s
));
240 k
[i
]->key
= str_to_wchar (fancy_key_name (c
));
243 k
[i
]->d
= str_to_wchar (desc
);
253 add_key_binding (&history_keys
, do_history_jump_next
, KEY_UP
,
254 _("history jump next"), 1);
255 add_key_binding (&history_keys
, do_history_jump_prev
, KEY_DOWN
,
256 _("history jump previous"), 1);
257 add_key_binding (&history_keys
, do_history_next
, KEY_RIGHT
, _("next move"),
259 add_key_binding (&history_keys
, do_history_prev
, KEY_LEFT
,
260 _("previous move"), 1);
261 add_key_binding (&history_keys
, do_history_half_move_toggle
, ' ',
262 _("toggle half move (ply) stepping"), 0);
263 add_key_binding (&history_keys
, do_history_rotate_board
, 'r',
264 _("rotate board"), 0);
265 add_key_binding (&history_keys
, do_history_jump
, 'j',
266 _("jump to move number"), 1);
267 add_key_binding (&history_keys
, do_history_find_new
, '/',
268 _("new move text expression"), 0);
269 add_key_binding (&history_keys
, do_history_find_next
, ']',
270 _("find next move text expression"), 1);
271 add_key_binding (&history_keys
, do_history_find_prev
, '[',
272 _("find previous move text expression"), 1);
273 add_key_binding (&history_keys
, do_history_annotate
, CTRL_KEY ('a'),
274 _("annotate the previous move"), 0);
275 add_key_binding (&history_keys
, do_history_rav_next
, '+',
276 _("next variation of the previous move"), 0);
277 add_key_binding (&history_keys
, do_history_rav_prev
, '-',
278 _("previous variation of the previous move"), 0);
279 add_key_binding (&history_keys
, do_history_menu
, 'M',
280 _("move history tree"), 0);
281 add_key_binding (&history_keys
, do_history_toggle
, 'h',
282 _("exit history mode"), 0);
284 add_key_binding (&edit_keys
, do_edit_select
, ' ',
285 _("select piece for movement"), 0);
286 add_key_binding (&edit_keys
, do_edit_commit
, '\n',
287 _("commit selected piece"), 0);
288 add_key_binding (&edit_keys
, do_edit_cancel_selected
, KEY_ESCAPE
,
289 _("cancel selected piece"), 0);
290 add_key_binding (&edit_keys
, do_edit_delete
, 'd',
291 _("remove the piece under the cursor"), 0);
292 add_key_binding (&edit_keys
, do_edit_insert
, 'i', _("insert piece"), 0);
293 add_key_binding (&edit_keys
, do_edit_toggle_castle
, 'c',
294 _("toggle castling availability"), 0);
295 add_key_binding (&edit_keys
, do_edit_enpassant
, 'p',
296 _("toggle enpassant square"), 0);
297 add_key_binding (&edit_keys
, do_edit_switch_turn
, 'w', _("toggle turn"), 0);
298 add_key_binding (&edit_keys
, do_edit_exit
, 'e', _("exit edit mode"), 0);
300 add_key_binding (&play_keys
, do_play_select
, ' ',
301 _("select piece for movement"), 0);
302 add_key_binding (&play_keys
, do_play_commit
, '\n',
303 _("commit selected piece"), 0);
304 add_key_binding (&play_keys
, do_play_cancel_selected
, KEY_ESCAPE
,
305 _("cancel selected piece"), 0);
306 add_key_binding (&play_keys
, do_play_set_clock
, 'C', _("set clock"), 0);
307 // add_key_binding(&play_keys, do_play_switch_turn, 'w', _("switch turn"), 0);
308 add_key_binding (&play_keys
, do_play_undo
, 'u', _("undo previous move"), 1);
309 add_key_binding (&play_keys
, do_play_go
, 'g',
310 _("force the chess engine to make the next move"), 0);
311 add_key_binding (&play_keys
, do_play_send_command
, '|',
312 _("send a command to the chess engine"), 0);
313 add_key_binding (&play_keys
, do_play_toggle_eh_mode
, 'w',
314 _("toggle engine/human play"), 0);
315 add_key_binding (&play_keys
, do_play_toggle_engine
, 'E',
316 _("toggle engine/engine play"), 0);
317 add_key_binding (&play_keys
, do_play_toggle_human
, 'H',
318 _("toggle human/human play"), 0);
319 add_key_binding (&play_keys
, do_play_toggle_pause
, 'p',
320 _("toggle pausing of this game"), 0);
321 add_key_binding (&play_keys
, do_play_history_mode
, 'h',
322 _("enter history mode"), 0);
323 add_key_binding (&play_keys
, do_play_edit_mode
, 'e', _("enter edit mode"),
325 add_key_binding (&play_keys
, do_play_toggle_strict_castling
,
326 CTRL_KEY ('p'), _("toggle strict castling"), 0);
328 add_key_binding (&global_keys
, do_global_tag_edit
, CTRL_KEY ('t'),
329 _("edit roster tags"), 0);
330 add_key_binding (&global_keys
, do_global_tag_view
, 't',
331 _("view roster tags"), 0);
332 add_key_binding (&global_keys
, do_global_find_new
, '?',
333 _("new find game expression"), 0);
334 add_key_binding (&global_keys
, do_global_find_next
, '}',
335 _("find next game"), 1);
336 add_key_binding (&global_keys
, do_global_find_prev
, '{',
337 _("find previous game"), 1);
338 add_key_binding (&global_keys
, do_global_new_game
, CTRL_KEY ('n'),
339 _("new game or round"), 0);
340 add_key_binding (&global_keys
, do_global_new_all
, CTRL_KEY ('k'),
341 _("new game from scratch"), 0);
342 add_key_binding (&global_keys
, do_global_copy_game
, CTRL_KEY ('i'),
343 _("copy current game"), 0);
344 add_key_binding (&global_keys
, do_global_copy_game_fen
, CTRL_KEY ('f'),
345 _("copy current game as FEN tag"), 0);
346 add_key_binding (&global_keys
, do_global_next_game
, '>', _("next game"), 1);
347 add_key_binding (&global_keys
, do_global_prev_game
, '<', _("previous game"),
349 add_key_binding (&global_keys
, do_global_game_jump
, 'J', _("jump to game"),
351 add_key_binding (&global_keys
, do_global_toggle_delete
, 'X',
352 _("toggle delete flag"), 1);
353 add_key_binding (&global_keys
, do_global_delete_game
, CTRL_KEY ('X'),
354 _("delete the current or flagged games"), 0);
355 add_key_binding (&global_keys
, do_global_resume_game
, CTRL_KEY ('r'),
356 _("load a PGN file"), 0);
357 add_key_binding (&global_keys
, do_global_save_game
, 's', _("save game"), 0);
358 add_key_binding (&global_keys
, do_global_toggle_board_details
,
359 CTRL_KEY ('d'), _("toggle board details"), 0);
360 add_key_binding (&global_keys
, do_global_toggle_engine_window
, 'W',
361 _("toggle chess engine IO window"), 0);
363 add_key_binding (&global_keys
, do_global_perl
, CTRL_KEY ('O'),
364 _("Call PERL subroutine"), 0);
366 add_key_binding (&global_keys
, do_global_about
, KEY_F (10),
367 _("version information"), 0);
368 add_key_binding (&global_keys
, do_global_redraw
, CTRL_KEY ('L'),
369 _("redraw the screen"), 0);
370 add_key_binding (&global_keys
, do_global_help
, KEY_F (1), NULL
, 0);
371 add_key_binding (&global_keys
, do_global_quit
, 'Q', _("quit"), 0);
375 set_config_defaults ()
379 config
.pattern
= strdup ("*.[Pp][Gg][Nn]*");
380 config
.engine_cmd
= strdup ("gnuchess --xboard");
381 config
.engine_protocol
= 1;
382 config
.jumpcount
= 5;
383 config
.linegraphics
= 1;
384 config
.saveprompt
= 1;
385 config
.deleteprompt
= 1;
386 config
.validmoves
= 1;
388 config
.showattacks
= 1;
389 config
.coordsyleft
= TRUE
;
390 config
.fmpolyglot
= FALSE
;
391 config
.boardleft
= TRUE
;
392 config
.exitdialogbox
= TRUE
;
393 config
.enginecmdblacktag
= TRUE
;
394 config
.bprevmove
= TRUE
;
395 config
.utf8_pieces
= 1;
396 config
.engine_timeout
= 10;
398 set_default_colors ();
400 if (stat (config
.nagfile
, &st
) == -1)
403 copydatafile (config
.nagfile
, "nag.data");
405 warn ("%s", config
.nagfile
);
408 if (stat (config
.ccfile
, &st
) == -1)
411 copydatafile (config
.ccfile
, "cc.data");
413 warn ("%s", config
.ccfile
);
418 update_key (struct key_s
**dst
, struct custom_key_s config_key
,
419 wint_t c
, char *desc
)
423 for (i
= 0; dst
[i
]; i
++)
425 if (dst
[i
]->f
== config_key
.func
)
432 dst
[i
]->key
= str_to_wchar (fancy_key_name (c
));
436 dst
[i
]->d
= str_to_wchar (desc
);
443 add_key_binding (&dst
, config_key
.func
, c
,
444 (desc
) ? desc
: _("no description"), config_key
.r
);
450 static struct known_key_s
479 KEY_ESCAPE
, "escape"},
487 parse_key (const char *filename
, int lines
, int word
, wchar_t ** key
)
489 wchar_t *p
= key
? *key
: NULL
;
490 wchar_t *orig
= key
? *key
: NULL
;
494 if (!key
|| !wcslen (*key
))
497 if (*p
== '\"' && !isspace (*(p
+1)))
509 for (i
= 0; known_keys
[i
].name
; i
++)
511 wchar_t *wc
= str_to_wchar (known_keys
[i
].name
);
513 if (!wcsncasecmp (p
, wc
, wcslen (wc
)))
516 p
+= strlen (known_keys
[i
].name
);
531 else if (*p
== 'F' || *p
== 'f')
533 char *str
= wchar_to_str (++p
);
535 c
= KEY_F (atoi (str
));
536 p
+= integer_len (atoi (str
));
545 errx (EXIT_FAILURE
, _("%s(%i): parse error \"%ls\""), filename
,
556 if (quote
&& *p
!= '\"')
557 errx (EXIT_FAILURE
, _("%s(%i): parse error \"%ls\""), filename
,
562 if (word
&& *p
&& !isspace (*p
))
563 errx (EXIT_FAILURE
, _("%s(%i): parse error \"%ls\""), filename
,
566 orig
+= wcslen (orig
) - wcslen (p
);
572 parse_key_binding (const char *filename
, int lines
, char *val
)
574 char mode
[64], func
[64];
575 wchar_t desc
[64] = { 0 };
585 n
= sscanf (val
, "%s %ls %s %63lc", mode
, key
, func
, desc
);
588 errx (EXIT_FAILURE
, _("%s(%i): too few arguments"), filename
, lines
);
590 if (strcasecmp (mode
, "history") == 0)
592 else if (strcasecmp (mode
, "play") == 0)
594 else if (strcasecmp (mode
, "edit") == 0)
596 else if (strcasecmp (mode
, "any") == 0)
599 errx (EXIT_FAILURE
, _("%s(%i): invalid game mode \"%s\""), filename
,
603 c
= parse_key (filename
, lines
, 1, &p
);
607 for (i
= 0; global_keys
[i
]; i
++)
609 if (global_keys
[i
]->c
== c
)
611 _("%s(%i): key \"%ls\" conflicts with a global key"),
612 filename
, lines
, key
);
616 for (f
= -2, i
= 0; config_keys
[i
].name
; i
++)
618 if (strcmp (config_keys
[i
].name
, func
) == 0 && config_keys
[i
].mode
== m
)
626 errx (EXIT_FAILURE
, _("%s(%i): invalid command \"%s\""), filename
,
629 str
= wchar_to_str (desc
);
634 update_key (play_keys
, config_keys
[f
], c
, (n
> 3) ? str
: NULL
);
637 update_key (history_keys
, config_keys
[f
], c
, (n
> 3) ? str
: NULL
);
640 update_key (edit_keys
, config_keys
[f
], c
, (n
> 3) ? str
: NULL
);
643 update_key (global_keys
, config_keys
[f
], c
, (n
> 3) ? str
: NULL
);
651 parse_macro_desc (const char *filename
, int lines
, wchar_t **val
)
655 wchar_t *buf
= Malloc (256 * sizeof (wchar_t));
661 for (p
= *val
; p
&& *p
; p
++)
674 else if (isspace (*p
) && !quote
)
680 if (!isspace (*p
) || !*(p
+1))
682 fprintf(stderr
, _ ("%s(%i): parse error\n"), filename
, lines
);
696 parse_macro (const char *filename
, int lines
, char *val
)
699 wchar_t keys
[2048] = { 0 }, key
[8];
706 n
= sscanf (val
, "%s %ls %2047lc", mode
, key
, keys
);
709 errx (EXIT_FAILURE
, _("%s(%i): too few arguments"), filename
, lines
);
711 if (strcasecmp (mode
, "history") == 0)
713 else if (strcasecmp (mode
, "play") == 0)
715 else if (strcasecmp (mode
, "edit") == 0)
717 else if (strcasecmp (mode
, "any") == 0)
720 errx (EXIT_FAILURE
, _("%s(%i): invalid game mode \"%s\""), filename
,
724 c
= parse_key (filename
, lines
, 1, &p
);
727 for (i
= 0; macros
[i
]; i
++);
729 macros
= Realloc (macros
, (i
+ 2) * sizeof (struct macro_s
*));
730 macros
[i
] = Calloc (1, sizeof (struct macro_s
));
735 macros
[i
]->desc
= parse_macro_desc (filename
, lines
, &p
);
736 if (!macros
[i
]->desc
)
739 while ((c
= parse_key (filename
, lines
, 0, &p
)) != 0)
741 macros
[i
]->keys
= Realloc (macros
[i
]->keys
, (macros
[i
]->total
+ 2) *
743 macros
[i
]->keys
[macros
[i
]->total
++] = c
;
750 parse_rcfile (const char *filename
)
753 char *line
, buf
[LINE_MAX
];
755 char *altengine
= NULL
;
760 if ((fp
= fopen (filename
, "r")) == NULL
)
761 err (EXIT_FAILURE
, "%s", filename
);
763 while ((line
= fgets (buf
, sizeof (buf
), fp
)) != NULL
)
766 char var
[30] = { 0 }, val
[LINE_MAX
- sizeof (var
) - 1] =
769 char token
[MAX_PGN_LINE_LEN
+ 1] = { 0 };
770 char value
[MAX_PGN_LINE_LEN
+ 1] = { 0 };
776 if (!line
[0] || line
[0] == '#')
779 if ((n
= sscanf (line
, "%s %[^\n]", var
, val
)) != 2)
780 errx (EXIT_FAILURE
, _("%s(%i): parse error %i"), filename
, lines
, n
);
782 p
= strdup (trim (val
));
783 strncpy (val
, p
, sizeof (val
) - 1);
785 p
= strdup (trim (var
));
786 strncpy (var
, p
, sizeof (var
) - 1);
789 if (strcmp (var
, "jump_count") == 0)
791 if (!isinteger (val
))
792 errx (EXIT_FAILURE
, _("%s(%i): value is not an integer"),
795 config
.jumpcount
= atoi (val
);
797 else if (strcmp (var
, "engine_init") == 0)
800 Realloc (config
.einit
, (init
+ 2) * sizeof (wchar_t *));
801 config
.einit
[init
++] = str_to_wchar (val
);
802 config
.einit
[init
] = NULL
;
804 else if (strcmp (var
, "pattern") == 0)
806 free (config
.pattern
);
807 config
.pattern
= strdup (val
);
809 else if (strcmp (var
, "mpl") == 0)
811 if (!isinteger (val
))
812 errx (EXIT_FAILURE
, _("%s(%i): value is not an integer"),
814 pgn_config_set (PGN_MPL
, atoi (val
));
816 else if (strcmp (var
, "stop_on_error") == 0)
817 pgn_config_set (PGN_STOP_ON_ERROR
, on_or_off (filename
, lines
, val
));
818 else if (strcmp (var
, "tag") == 0)
820 if ((n
= sscanf (val
, "%s %s ", token
, value
)) < 1 || n
> 2)
821 errx (EXIT_FAILURE
, _("%s(%i): invalid value \"%s\""), filename
,
828 p
= val
+ strlen (token
);
829 strncpy (value
, p
, sizeof (value
) - 1);
832 for (n
= 0; n
< strlen (token
); n
++)
834 if (!isalnum (token
[n
]) && token
[n
] != '_')
836 _("%s(%i): token names must match 0-9A-Za-z_."),
840 token
[0] = toupper (token
[0]);
841 pgn_tag_add (&config
.tag
, token
, value
);
843 else if (strcmp (var
, "save_directory") == 0)
844 config
.savedirectory
= strdup (val
);
845 else if (strcmp (var
, "line_graphics") == 0)
846 config
.linegraphics
= on_or_off (filename
, lines
, val
);
847 else if (strcmp (var
, "save_prompt") == 0)
848 config
.saveprompt
= on_or_off (filename
, lines
, val
);
849 else if (strcmp (var
, "delete_prompt") == 0)
850 config
.deleteprompt
= on_or_off (filename
, lines
, val
);
851 else if (strcmp (var
, "valid_moves") == 0)
852 config
.validmoves
= on_or_off (filename
, lines
, val
);
853 else if (strcmp (var
, "board_details") == 0)
854 config
.details
= on_or_off (filename
, lines
, val
);
855 else if (strcmp (var
, "show_attacks") == 0)
856 config
.showattacks
= on_or_off (filename
, lines
, val
);
857 else if (strcmp (var
, "coords_y_left") == 0)
858 config
.coordsyleft
= on_or_off (filename
, lines
, val
);
859 else if (strcmp (var
, "fm_polyglot") == 0)
860 config
.fmpolyglot
= on_or_off (filename
, lines
, val
);
861 else if (strcmp (var
, "board_left") == 0)
862 config
.boardleft
= on_or_off (filename
, lines
, val
);
863 else if (strcmp (var
, "exit_dialog_box") == 0)
864 config
.exitdialogbox
= on_or_off (filename
, lines
, val
);
865 else if (strcmp (var
, "engine_cmd_blacktag") == 0)
866 config
.enginecmdblacktag
= on_or_off (filename
, lines
, val
);
867 else if (strcmp (var
, "board_prev_move") == 0)
868 config
.bprevmove
= on_or_off (filename
, lines
, val
);
869 else if (strcmp (var
, "strict_castling") == 0)
870 pgn_config_set (PGN_STRICT_CASTLING
,
871 on_or_off (filename
, lines
, val
));
872 else if (strcmp (var
, "engine_cmd") == 0)
873 altengine
= strdup (val
);
874 else if (strcmp (var
, "engine_protocol") == 0)
876 if (!isinteger (val
))
877 errx (EXIT_FAILURE
, _("%s(%i): value is not an integer"),
880 config
.engine_protocol
= atoi (val
);
882 if (config
.engine_protocol
!= 1 && config
.engine_protocol
!= 2)
883 errx (EXIT_FAILURE
, _("%s(%i): invalid value"), filename
, lines
);
885 else if (strcmp (var
, "engine_timeout") == 0)
886 config
.engine_timeout
= atoi (val
);
887 else if (strcmp (var
, "utf8_pieces") == 0)
888 config
.utf8_pieces
= on_or_off (filename
, lines
, val
);
889 else if (strcmp (var
, "turn_cmd") == 0)
890 config
.turn_cmd
= strdup (val
);
891 else if (strcmp (var
, "color_board_window") == 0)
892 parse_color (filename
, lines
, val
, &config
.color
[CONF_BDWINDOW
]);
893 else if (strcmp (var
, "color_board_selected") == 0)
894 parse_color (filename
, lines
, val
, &config
.color
[CONF_BSELECTED
]);
895 else if (strcmp (var
, "color_board_white_moves") == 0)
896 parse_color (filename
, lines
, val
, &config
.color
[CONF_BMOVESW
]);
897 else if (strcmp (var
, "color_board_black_moves") == 0)
898 parse_color (filename
, lines
, val
, &config
.color
[CONF_BMOVESB
]);
899 else if (strcmp (var
, "color_board_count") == 0)
900 parse_color (filename
, lines
, val
, &config
.color
[CONF_BCOUNT
]);
901 else if (strcmp (var
, "color_board_cursor") == 0)
902 parse_color (filename
, lines
, val
, &config
.color
[CONF_BCURSOR
]);
903 else if (strcmp (var
, "color_board_black") == 0)
904 parse_color (filename
, lines
, val
, &config
.color
[CONF_BBLACK
]);
905 else if (strcmp (var
, "color_board_white") == 0)
906 parse_color (filename
, lines
, val
, &config
.color
[CONF_BWHITE
]);
907 else if (strcmp (var
, "color_board_graphics") == 0)
908 parse_color (filename
, lines
, val
, &config
.color
[CONF_BGRAPHICS
]);
909 else if (strcmp (var
, "color_board_coords") == 0)
910 parse_color (filename
, lines
, val
, &config
.color
[CONF_BCOORDS
]);
911 else if (strcmp (var
, "color_board_castling") == 0)
912 parse_color (filename
, lines
, val
, &config
.color
[CONF_BCASTLING
]);
913 else if (strcmp (var
, "color_board_enpassant") == 0)
914 parse_color (filename
, lines
, val
, &config
.color
[CONF_BENPASSANT
]);
915 else if (strcmp (var
, "color_board_attack") == 0)
916 parse_color (filename
, lines
, val
, &config
.color
[CONF_BATTACK
]);
917 else if (strcmp (var
, "color_board_prev_move") == 0)
918 parse_color (filename
, lines
, val
, &config
.color
[CONF_BPREVMOVE
]);
919 else if (strcmp (var
, "color_status_window") == 0)
920 parse_color (filename
, lines
, val
, &config
.color
[CONF_SWINDOW
]);
921 else if (strcmp (var
, "color_status_title") == 0)
922 parse_color (filename
, lines
, val
, &config
.color
[CONF_STITLE
]);
923 else if (strcmp (var
, "color_status_border") == 0)
924 parse_color (filename
, lines
, val
, &config
.color
[CONF_SBORDER
]);
925 else if (strcmp (var
, "color_status_notify") == 0)
926 parse_color (filename
, lines
, val
, &config
.color
[CONF_SNOTIFY
]);
927 else if (strcmp (var
, "color_status_engine") == 0)
928 parse_color (filename
, lines
, val
, &config
.color
[CONF_SENGINE
]);
929 else if (strcmp (var
, "color_tag_window") == 0)
930 parse_color (filename
, lines
, val
, &config
.color
[CONF_TWINDOW
]);
931 else if (strcmp (var
, "color_tag_title") == 0)
932 parse_color (filename
, lines
, val
, &config
.color
[CONF_TTITLE
]);
933 else if (strcmp (var
, "color_tag_border") == 0)
934 parse_color (filename
, lines
, val
, &config
.color
[CONF_TBORDER
]);
935 else if (strcmp (var
, "color_history_window") == 0)
936 parse_color (filename
, lines
, val
, &config
.color
[CONF_HWINDOW
]);
937 else if (strcmp (var
, "color_history_title") == 0)
938 parse_color (filename
, lines
, val
, &config
.color
[CONF_HTITLE
]);
939 else if (strcmp (var
, "color_history_border") == 0)
940 parse_color (filename
, lines
, val
, &config
.color
[CONF_HBORDER
]);
941 else if (strcmp (var
, "color_message_window") == 0)
942 parse_color (filename
, lines
, val
, &config
.color
[CONF_MWINDOW
]);
943 else if (strcmp (var
, "color_message_title") == 0)
944 parse_color (filename
, lines
, val
, &config
.color
[CONF_MTITLE
]);
945 else if (strcmp (var
, "color_message_border") == 0)
946 parse_color (filename
, lines
, val
, &config
.color
[CONF_MBORDER
]);
947 else if (strcmp (var
, "color_message_prompt") == 0)
948 parse_color (filename
, lines
, val
, &config
.color
[CONF_MPROMPT
]);
949 else if (strcmp (var
, "color_input_window") == 0)
950 parse_color (filename
, lines
, val
, &config
.color
[CONF_IWINDOW
]);
951 else if (strcmp (var
, "color_input_title") == 0)
952 parse_color (filename
, lines
, val
, &config
.color
[CONF_ITITLE
]);
953 else if (strcmp (var
, "color_input_border") == 0)
954 parse_color (filename
, lines
, val
, &config
.color
[CONF_IBORDER
]);
955 else if (strcmp (var
, "color_input_prompt") == 0)
956 parse_color (filename
, lines
, val
, &config
.color
[CONF_IPROMPT
]);
957 else if (strcmp (var
, "color_menu") == 0)
958 parse_color (filename
, lines
, val
, &config
.color
[CONF_MENU
]);
959 else if (strcmp (var
, "color_menu_selected") == 0)
960 parse_color (filename
, lines
, val
, &config
.color
[CONF_MENUS
]);
961 else if (strcmp (var
, "color_menu_highlight") == 0)
962 parse_color (filename
, lines
, val
, &config
.color
[CONF_MENUH
]);
963 else if (strcmp (var
, "color_menu_graphics") == 0)
964 parse_color (filename
, lines
, val
,
965 &config
.color
[CONF_HISTORY_MENU_LG
]);
966 else if (strcmp (var
, "bind") == 0)
967 parse_key_binding (filename
, lines
, val
);
968 else if (strcmp (var
, "macro") == 0)
969 parse_macro (filename
, lines
, val
);
970 else if (strcmp (var
, "cbind") == 0)
972 config
.keys
= Realloc (config
.keys
, (k
+ 2) *
973 sizeof (struct config_key_s
*));
974 config
.keys
[k
] = Calloc (1, sizeof (struct config_key_s
));
978 while (*p
&& !isspace (*p
))
985 if (strcasecmp (p
, "none") == 0)
986 config
.keys
[k
]->type
= KEY_DEFAULT
;
987 else if (strcasecmp (p
, "repeat") == 0)
988 config
.keys
[k
]->type
= KEY_REPEAT
;
989 else if (strcasecmp (p
, "set") == 0)
990 config
.keys
[k
]->type
= KEY_SET
;
992 errx (EXIT_FAILURE
, _("%s(%i): invalid value \"%s\""), filename
,
998 while (*p
&& isspace (*p
))
1001 config
.keys
[k
]->c
= *p
++;
1003 while (isspace (*p
))
1006 config
.keys
[k
++]->str
= str_to_wchar (p
);
1007 config
.keys
[k
] = NULL
;
1010 errx (EXIT_FAILURE
, _("%s(%i): invalid parameter \"%s\""), filename
,
1018 free (config
.engine_cmd
);
1019 config
.engine_cmd
= NULL
;
1020 config
.engine_cmd
= altengine
;
1023 if (config
.enginecmdblacktag
)
1024 pgn_tag_add (&config
.tag
, (char *) "Black", config
.engine_cmd
);
1027 static struct key_s
*
1028 find_key (struct key_s
**keys
, key_func f
)
1032 for (i
= 0; keys
[i
]; i
++)
1034 if (keys
[i
]->f
== f
)
1042 key_lookup (struct key_s
**keys
, key_func f
)
1044 struct key_s
*k
= find_key (keys
, f
);
1046 return k
? k
->key
: NULL
;
1050 keycode_lookup (struct key_s
**keys
, key_func f
)
1052 struct key_s
*k
= find_key (keys
, f
);
1054 return k
? k
->c
: 0;