Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ui_tcltk.h
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2015 Fulvio Benini
3 
4 * This file is part of Scid (Shane's Chess Information Database).
5 *
6 * Scid is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
9 *
10 * Scid 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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Scid. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef SCID_UI_TCLTK_H
20 #define SCID_UI_TCLTK_H
21 
22 #include "timer.h"
23 #include <tcl.h>
24 #include <sstream>
25 #include <limits>
26 
27 namespace UI_impl {
28 
29 
30 typedef int UI_res_t;
31 typedef ClientData UI_extra_t;
32 typedef Tcl_Interp* UI_handle_t;
33 
34 inline int initTclTk (UI_handle_t ti);
35 
36 inline int Main (int argc, char* argv[], void (*exit) (void*)) {
37  Tcl_FindExecutable(argv[0]);
38  Tcl_CreateExitHandler(exit, 0);
39  bool search_tcl = (argc == 1) ? true : false;
40  if (argc > 1 && argc < 10) {
41  char* ext = strrchr (argv[1], '.');
42  if (ext != 0 && strlen(ext) == 4 && std::string(".tcl") != ext) {
43  search_tcl = true;
44  }
45  }
46  if (search_tcl) {
47  char sourceFileName [4096] = {0};
48  #ifndef WIN32
49  // Expand symbolic links
50  char* exec_name = realpath(Tcl_GetNameOfExecutable(), 0);
51  strncpy(sourceFileName, exec_name, 4000);
52  free(exec_name);
53  #else
54  strncpy(sourceFileName, Tcl_GetNameOfExecutable(), 4000);
55  #endif
56 
57  char* dirname = strrchr(sourceFileName, '/');
58  if (dirname == 0) dirname = sourceFileName;
59  else dirname += 1;
60  strcpy (dirname, "tcl/start.tcl");
61  if (0 != Tcl_Access(sourceFileName, 4)) {
62  strcpy (dirname, "../tcl/start.tcl");
63  }
64  char* newArgv[10] = { argv[0], sourceFileName };
65  std::copy(argv + 1, argv + argc, newArgv + 2);
66  Tcl_Main(argc + 1, newArgv, UI_impl::initTclTk);
67  } else {
68  Tcl_Main (argc, argv, UI_impl::initTclTk);
69  }
70 
71  return 0;
72 }
73 
74 
75 class tcl_Progress : public Progress::Impl {
76  UI_handle_t ti_;
77  Timer timer_;
78 
79 public:
80  tcl_Progress(UI_handle_t ti) : ti_(ti) {}
81  virtual ~tcl_Progress() {}
82 
83  virtual bool report(size_t done, size_t total, const char* msg) {
84  ASSERT(done <= static_cast<size_t>(std::numeric_limits<int>::max()));
85  ASSERT(total <= static_cast<size_t>(std::numeric_limits<int>::max()));
86 
87  uint64_t elapsed = timer_.MilliSecs();
88  uint64_t estimated = (done == 0) ? 0 : elapsed * total / done;
89  Tcl_Obj* tmp[5];
90  tmp[0] = Tcl_NewStringObj("::progressCallBack", -1);
91  tmp[1] = Tcl_NewIntObj(static_cast<int>(done));
92  tmp[2] = Tcl_NewIntObj(static_cast<int>(total));
93  tmp[3] = Tcl_NewIntObj(static_cast<int>(elapsed / 1000));
94  tmp[4] = Tcl_NewIntObj(static_cast<int>(estimated / 1000));
95  Tcl_Obj* cmd = Tcl_NewListObj(5, tmp);
96  if (msg != NULL)
97  Tcl_ListObjAppendElement(ti_, cmd, Tcl_NewStringObj(msg, -1));
98  Tcl_IncrRefCount(cmd);
99  int res = Tcl_EvalObjEx(ti_, cmd, TCL_EVAL_GLOBAL);
100  Tcl_DecrRefCount(cmd);
101  return res == TCL_OK;
102  }
103 };
104 
106  UI_handle_t ti_;
107 
108 public:
109  tcl_ProgressPosMask(UI_handle_t ti) : ti_(ti) {}
110  virtual ~tcl_ProgressPosMask() {}
111 
112  virtual bool report(size_t, size_t, const char*) {
113  return TCL_OK == Tcl_EvalEx(ti_, "::windows::gamelist::PosMaskProgress", -1, 0);
114  }
115 };
116 
117 inline Progress CreateProgress(UI_handle_t data) {
118  int err = Tcl_EvalEx(data, "::progressCallBack init", -1, 0);
119  if (err != TCL_OK) return Progress();
120  return Progress(new UI_impl::tcl_Progress(data));
121 }
122 
123 inline Progress CreateProgressPosMask(UI_handle_t data) {
124  return Progress(new UI_impl::tcl_ProgressPosMask(data));
125 }
126 
127 
128 class List {
129  Tcl_Obj** list_;
130  mutable int i_;
131  Tcl_Obj* stackBuf_[6];
132 
133  friend Tcl_Obj* ObjMaker(const List&);
134 
135 public:
136  explicit List(size_t max_size)
137  : list_(stackBuf_), i_(0) {
138  const size_t stackBuf_size = sizeof(stackBuf_)/sizeof(stackBuf_[0]);
139  if (max_size > stackBuf_size) {
140  list_ = new Tcl_Obj*[max_size];
141  }
142  }
143 
144  ~List() {
145  clear();
146  if (list_ != stackBuf_) delete [] list_;
147  }
148 
149  void clear() {
150  for (int i=0; i < i_; i++) Tcl_DecrRefCount(list_[i]);
151  i_ = 0;
152  }
153 
154  void push_back(Tcl_Obj* value) {
155  ASSERT(value != 0);
156  list_[i_++] = value;
157  }
158  template <typename T>
159  void push_back(const T& value);
160 };
161 
162 inline Tcl_Obj* ObjMaker(bool v) {
163  return Tcl_NewBooleanObj(v);
164 }
165 inline Tcl_Obj* ObjMaker(int v) {
166  return Tcl_NewIntObj(v);
167 }
168 inline Tcl_Obj* ObjMaker(unsigned int v) {
169  ASSERT(v <= static_cast<unsigned int>(std::numeric_limits<int>::max()));
170  return Tcl_NewIntObj(static_cast<int>(v));
171 }
172 inline Tcl_Obj* ObjMaker(unsigned long v) {
173  ASSERT(v <= static_cast<unsigned long>(std::numeric_limits<int>::max()));
174  return Tcl_NewIntObj(static_cast<int>(v));
175 }
176 inline Tcl_Obj* ObjMaker(unsigned long long v) {
177  ASSERT(v <= static_cast<unsigned long long>(std::numeric_limits<int>::max()));
178  return Tcl_NewIntObj(static_cast<int>(v));
179 }
180 inline Tcl_Obj* ObjMaker(double v) {
181  return Tcl_NewDoubleObj(v);
182 }
183 inline Tcl_Obj* ObjMaker(const char* s) {
184  return Tcl_NewStringObj(s, -1);
185 }
186 inline Tcl_Obj* ObjMaker(const std::string& s) {
187  ASSERT(s.size() <= static_cast<size_t>(std::numeric_limits<int>::max()));
188  return Tcl_NewStringObj(s.c_str(), static_cast<int>(s.size()));
189 }
190 inline Tcl_Obj* ObjMaker(const List& v) {
191  Tcl_Obj* res = Tcl_NewListObj(v.i_, v.list_);
192  v.i_ = 0;
193  return res;
194 }
195 
196 template <typename T>
197 inline void List::push_back(const T& value) {
198  push_back(ObjMaker(value));
199 }
200 
201 
202 inline UI_res_t ResultHelper(UI_handle_t ti, errorT res) {
203  if (res == OK) return TCL_OK;
204  Tcl_SetObjErrorCode(ti, Tcl_NewIntObj(res));
205  return TCL_ERROR;
206 }
207 
208 inline UI_res_t Result(UI_handle_t ti, errorT res) {
209  Tcl_ResetResult(ti);
210  return UI_impl::ResultHelper(ti, res);
211 }
212 
213 template <typename T>
214 inline UI_res_t Result(UI_handle_t ti, errorT res, const T& value) {
215  Tcl_SetObjResult(ti, UI_impl::ObjMaker(value));
216  return UI_impl::ResultHelper(ti, res);
217 }
218 
219 } //End of UI_impl namespace
220 
221 
222 //TODO:
223 //Duplicate declarations (already in ui.h)
226 UI_impl::UI_res_t sc_base (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
227 UI_impl::UI_res_t sc_book (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
229 UI_impl::UI_res_t sc_eco (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
231 UI_impl::UI_res_t sc_game (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
232 UI_impl::UI_res_t sc_info (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
233 UI_impl::UI_res_t sc_move (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
234 UI_impl::UI_res_t sc_name (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
236 UI_impl::UI_res_t sc_pos (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
238 UI_impl::UI_res_t sc_tree (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
239 UI_impl::UI_res_t sc_var (UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char ** argv);
240 
241 inline int UI_impl::initTclTk (UI_handle_t ti)
242 {
243  if (Tcl_Init (ti) == TCL_ERROR) { return TCL_ERROR; }
244 
245  Tcl_CreateCommand(ti, "strIsPrefix" , str_is_prefix , 0, NULL);
246  Tcl_CreateCommand(ti, "strPrefixLen", str_prefix_len, 0, NULL);
247  Tcl_CreateCommand(ti, "sc_base" , sc_base , 0, NULL);
248  Tcl_CreateCommand(ti, "sc_book" , sc_book , 0, NULL);
249  Tcl_CreateCommand(ti, "sc_clipbase" , sc_clipbase , 0, NULL);
250  Tcl_CreateCommand(ti, "sc_eco" , sc_eco , 0, NULL);
251  Tcl_CreateCommand(ti, "sc_filter" , sc_filter , 0, NULL);
252  Tcl_CreateCommand(ti, "sc_game" , sc_game , 0, NULL);
253  Tcl_CreateCommand(ti, "sc_info" , sc_info , 0, NULL);
254  Tcl_CreateCommand(ti, "sc_move" , sc_move , 0, NULL);
255  Tcl_CreateCommand(ti, "sc_name" , sc_name , 0, NULL);
256  Tcl_CreateCommand(ti, "sc_report" , sc_report , 0, NULL);
257  Tcl_CreateCommand(ti, "sc_pos" , sc_pos , 0, NULL);
258  Tcl_CreateCommand(ti, "sc_search" , sc_search , 0, NULL);
259  Tcl_CreateCommand(ti, "sc_tree" , sc_tree , 0, NULL);
260  Tcl_CreateCommand(ti, "sc_var" , sc_var , 0, NULL);
261 
262  return TCL_OK;
263 }
264 
265 
266 #endif
long long MilliSecs(void) const
Definition: timer.h:28
Definition: timer.h:23
virtual bool report(size_t done, size_t total, const char *msg)
Definition: ui_tcltk.h:83
virtual ~tcl_Progress()
Definition: ui_tcltk.h:81
const errorT OK
Definition: error.h:23
uint max(int a, int b)
Definition: crosstab.cpp:237
#define ASSERT(f)
Definition: common.h:59
Definition: misc.h:63
UI_impl::UI_res_t sc_move(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:5033
UI_impl::UI_res_t str_is_prefix(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:294
Tcl_Obj * ObjMaker(bool v)
Definition: ui_tcltk.h:162
int UI_res_t
Definition: ui_tcltk.h:30
tcl_ProgressPosMask(UI_handle_t ti)
Definition: ui_tcltk.h:109
UI_res_t ResultHelper(UI_handle_t ti, errorT res)
Definition: ui_tcltk.h:202
UI_impl::UI_res_t sc_game(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
GAME functions.
Definition: tkscid.cpp:2091
int initTclTk(UI_handle_t ti)
Definition: ui_tcltk.h:241
UI_impl::UI_res_t sc_var(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:9527
virtual bool report(size_t, size_t, const char *)
Definition: ui_tcltk.h:112
UI_impl::UI_res_t sc_name(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
UI_impl::UI_res_t sc_report(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:7516
UI_res_t Result(UI_handle_t ti, errorT res)
Definition: ui_tcltk.h:208
UI_impl::UI_res_t str_prefix_len(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:308
Progress CreateProgressPosMask(UI_handle_t data)
Definition: ui_tcltk.h:123
unsigned short errorT
Definition: error.h:20
void push_back(Tcl_Obj *value)
Definition: ui_tcltk.h:154
UI_impl::UI_res_t sc_clipbase(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
CLIPBASE functions.
Definition: tkscid.cpp:1193
clear?pattern?
We don&#39;t remove TooltipMenu because there.
int Main(int argc, char *argv[], void(*exit)(void *))
Definition: ui_tcltk.h:36
UI_impl::UI_res_t sc_tree(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:7870
tcl_Progress(UI_handle_t ti)
Definition: ui_tcltk.h:80
UI_impl::UI_res_t sc_search(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:8488
Tcl_Interp * UI_handle_t
Definition: ui_tcltk.h:32
cmd
Definition: fics.tcl:439
UI_impl::UI_res_t sc_eco(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:1248
List(size_t max_size)
Definition: ui_tcltk.h:136
Progress CreateProgress(UI_handle_t data)
Definition: ui_tcltk.h:117
UI_impl::UI_res_t sc_pos(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:5269
UI_impl::UI_res_t sc_filter(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
UI_impl::UI_res_t sc_info(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
Definition: tkscid.cpp:4813
void clear()
Definition: ui_tcltk.h:149
UI_impl::UI_res_t sc_book(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
BOOK functions.
Definition: tkscid.cpp:9658
UI_impl::UI_res_t sc_base(UI_impl::UI_extra_t, UI_impl::UI_handle_t, int argc, const char **argv)
ClientData UI_extra_t
Definition: ui_tcltk.h:31