OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [libgui/] [src/] [tclgetdir.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* tclgetdir.c -- TCL code to browse for a directory.
2
   Copyright (C) 1997, 1998 Cygnus Solutions.
3
   Written by Ian Lance Taylor <ian@cygnus.com>.  */
4
 
5
#ifdef _WIN32
6
#include <windows.h>
7
#ifndef _GNU_H_WINDOWS_H   /* if not using old Cygwin Win32 headers */
8
#include <shlobj.h>
9
#endif
10
#endif
11
 
12
#include <tcl.h>
13
#include <tk.h>
14
 
15
#include "guitcl.h"
16
 
17
/* This file defines one TCL command.
18
 
19
   ide_get_directory
20
       Allows the user to select a directory.  Returns the selected
21
       directory as a string.  */
22
 
23
#ifdef _WIN32
24
 
25
#include <tkWinInt.h>
26
/* a call back to set the initial selected directory */
27
 
28
/* defines currently missing from Cygwin32 */
29
#ifndef BFFM_INITIALIZED
30
 
31
 
32
LPITEMIDLIST WINAPI SHBrowseForFolderA(LPBROWSEINFO lpbi);
33
 
34
/* message from browser */
35
#define BFFM_INITIALIZED        1
36
#define BFFM_SELCHANGED         2
37
 
38
/* messages to browser */
39
#define BFFM_SETSTATUSTEXTA     (WM_USER + 100)
40
#define BFFM_ENABLEOK           (WM_USER + 101)
41
#define BFFM_SETSELECTIONA      (WM_USER + 102)
42
#define BFFM_SETSELECTIONW      (WM_USER + 103)
43
#define BFFM_SETSTATUSTEXTW     (WM_USER + 104)
44
 
45
#ifdef UNICODE
46
#define SHBrowseForFolder   SHBrowseForFolderW
47
#define BFFM_SETSTATUSTEXT  BFFM_SETSTATUSTEXTW
48
#define BFFM_SETSELECTION   BFFM_SETSELECTIONW
49
#else
50
#define SHBrowseForFolder   SHBrowseForFolderA
51
#define BFFM_SETSTATUSTEXT  BFFM_SETSTATUSTEXTA
52
#define BFFM_SETSELECTION   BFFM_SETSELECTIONA
53
#endif
54
 
55
#endif /* ! BFFM_INITIALIZED */
56
 
57
/* FIXME: We need to dig into the Tk window implementation internals.  */
58
 
59
int CALLBACK MyBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
60
{
61
  if (uMsg==BFFM_INITIALIZED)
62
    {
63
       SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)lpData);
64
    }
65
  return 0;
66
}
67
 
68
/* Implement the Windows version of the ide_get_directory command.  */
69
static int
70
get_directory_command (ClientData cd, Tcl_Interp *interp, int argc,
71
                       char **argv)
72
{
73
  BROWSEINFO bi;
74
  char buf[MAX_PATH + 1];
75
  Tk_Window parent;
76
  int i, oldMode;
77
  LPITEMIDLIST idlist;
78
  char *p;
79
  int atts;
80
  Tcl_DString tempBuffPtr;
81
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
82
  Tcl_DString titleDString;
83
  Tcl_DString initialDirDString;
84
  Tcl_DString resultDString;
85
 
86
  Tcl_DStringInit(&titleDString);
87
  Tcl_DStringInit(&initialDirDString);
88
#endif
89
 
90
  Tcl_DStringInit(&tempBuffPtr);
91
 
92
  bi.hwndOwner = NULL;
93
  bi.pidlRoot = NULL;
94
  bi.pszDisplayName = buf;
95
  bi.lpszTitle = NULL;
96
  bi.ulFlags = 0;
97
  bi.lpfn = NULL;
98
  bi.lParam = 0;
99
  bi.iImage = 0;
100
 
101
  parent = Tk_MainWindow (interp);
102
 
103
  for (i = 1; i < argc; i += 2)
104
    {
105
      int v;
106
      int len;
107
 
108
      v = i + 1;
109
      len = strlen (argv[i]);
110
 
111
      if (strncmp (argv[i], "-parent", len) == 0)
112
        {
113
          if (v == argc)
114
            goto arg_missing;
115
 
116
          parent = Tk_NameToWindow (interp, argv[v],
117
                                    Tk_MainWindow (interp));
118
          if (parent == NULL)
119
            return TCL_ERROR;
120
        }
121
      else if (strncmp (argv[i], "-title", len) == 0)
122
        {
123
 
124
          if (v == argc)
125
            goto arg_missing;
126
 
127
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
128
          Tcl_UtfToExternalDString(NULL, argv[v], -1, &titleDString);
129
          bi.lpszTitle = Tcl_DStringValue(&titleDString);
130
#else
131
          bi.lpszTitle = argv[v];
132
#endif
133
        }
134
      else if (strncmp (argv[i], "-initialdir", len) == 0)
135
        {
136
          if (v == argc)
137
            goto arg_missing;
138
 
139
          /* bi.lParam will be passed to the callback function.(save the need for globals)*/
140
          bi.lParam = (LPARAM) Tcl_TranslateFileName(interp, argv[v], &tempBuffPtr);
141
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
142
          Tcl_UtfToExternalDString(NULL, (char *) bi.lParam, -1, &initialDirDString);
143
          bi.lParam = (LPARAM) Tcl_DStringValue(&initialDirDString);
144
#endif
145
          bi.lpfn   = MyBrowseCallbackProc;
146
        }
147
      else
148
        {
149
          Tcl_AppendResult (interp, "unknown option \"", argv[i],
150
                            "\", must be -parent or -title", (char *) NULL);
151
          return TCL_ERROR;
152
        }
153
    }
154
 
155
  if (Tk_WindowId (parent) == None)
156
    Tk_MakeWindowExist (parent);
157
 
158
  bi.hwndOwner = Tk_GetHWND (Tk_WindowId (parent));
159
 
160
  oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
161
  idlist = SHBrowseForFolder (&bi);
162
  Tcl_SetServiceMode(oldMode);
163
 
164
  if (idlist == NULL)
165
    {
166
      /* User pressed the cancel button.  */
167
      return TCL_OK;
168
    }
169
 
170
  if (! SHGetPathFromIDList (idlist, buf))
171
    {
172
      Tcl_SetResult (interp, "could not get path for directory", TCL_STATIC);
173
      return TCL_ERROR;
174
    }
175
 
176
  /* Ensure the directory exists.  */
177
  atts = GetFileAttributesA (buf);
178
  if (atts == -1 || ! (atts & FILE_ATTRIBUTE_DIRECTORY))
179
    {
180
      Tcl_AppendResult (interp, "path \"", buf, "\" is not a directory",
181
                        (char *) NULL);
182
      /* FIXME: free IDLIST.  */
183
      return TCL_ERROR;
184
    }
185
 
186
  /* FIXME: We are supposed to free IDLIST using the shell task
187
     allocator, but cygwin32 doesn't define the required interfaces
188
     yet.  */
189
 
190
 
191
 
192
  /* Normalize the path for Tcl.  */
193
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
194
  Tcl_ExternalToUtfDString(NULL, buf, -1, &resultDString);
195
  p = Tcl_DStringValue(&resultDString);
196
#else
197
  p = buf;
198
#endif
199
  for (; *p != '\0'; ++p)
200
    if (*p == '\\')
201
      *p = '/';
202
 
203
  Tcl_ResetResult(interp);
204
#if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >= 1)
205
  Tcl_SetResult(interp, Tcl_DStringValue(&resultDString), TCL_VOLATILE);
206
  Tcl_DStringFree(&resultDString);
207
  Tcl_DStringFree(&titleDString);
208
  Tcl_DStringFree(&initialDirDString);
209
#else
210
  Tcl_SetResult(interp, buf, TCL_VOLATILE);
211
#endif
212
  Tcl_DStringFree(&tempBuffPtr);
213
 
214
  return TCL_OK;
215
 
216
 arg_missing:
217
  Tcl_AppendResult(interp, "value for \"", argv[argc - 1], "\" missing",
218
                   NULL);
219
  return TCL_ERROR;
220
}
221
 
222
 
223
#else /* ! _WIN32 */
224
 
225
/* Use our modified file dialog, and hope the user picks a directory.  */
226
 
227
static int
228
get_directory_command (ClientData cd, Tcl_Interp *interp, int argc,
229
                       char **argv)
230
{
231
  char **new_args;
232
  char *merge;
233
  int result, i;
234
 
235
  /* We can't directly run Tk_GetOpenFile, because it wants some
236
     ClientData that we're best off not knowing.  So instead we
237
     re-eval.  This is a lot less efficient, but it doesn't really
238
     matter.  */
239
 
240
  new_args = (char **) Tcl_Alloc ((argc + 2) * sizeof (char *));
241
 
242
  new_args[0] = "tk_getOpenFile";
243
  new_args[1] = "-choosedir";
244
  new_args[2] = "1";
245
 
246
  for (i = 1; i < argc; ++i)
247
    new_args[2 + i] = argv[i];
248
 
249
  merge = Tcl_Merge (argc + 2, new_args);
250
  result = Tcl_GlobalEval (interp, merge);
251
 
252
  Tcl_Free (merge);
253
  Tcl_Free ((char *) new_args);
254
 
255
  return result;
256
}
257
 
258
#endif /* ! _WIN32 */
259
 
260
/* This function creates the ide_get_directory TCL command.  */
261
 
262
int
263
ide_create_get_directory_command (Tcl_Interp *interp)
264
{
265
  if (Tcl_CreateCommand (interp, "ide_get_directory", get_directory_command,
266
                         NULL, NULL) == NULL)
267
    return TCL_ERROR;
268
  return TCL_OK;
269
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.