Mercurial > dwindows
annotate win/dirent.c @ 916:44a0f9a2e8f9
Experimental change, pulling the resize event handling out of the resizer code on Mac.
Wait until sizing is complete then take another pass through the window and generate any required events.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Fri, 22 Apr 2011 03:59:29 +0000 |
parents | 1e3ab8adba90 |
children | 412af8059331 |
rev | line source |
---|---|
3 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <ctype.h> | |
5 | |
6 #include <windows.h> | |
7 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
8 #include "compat.h" |
3 | 9 #include <errno.h> |
10 | |
11 #define error(rc) errno = 255 | |
12 | |
13 struct _dirdescr { | |
14 HANDLE handle; /* DosFindFirst handle */ | |
15 char fstype; /* filesystem type */ | |
16 long count; /* valid entries in <ffbuf> */ | |
17 long number; /* absolute number of next entry */ | |
18 int index; /* relative number of next entry */ | |
19 char name[MAXPATHLEN+3]; /* directory name */ | |
20 unsigned attrmask; /* attribute mask for seekdir */ | |
21 struct dirent entry; /* buffer for directory entry */ | |
22 WIN32_FIND_DATA data; | |
23 }; | |
24 | |
25 /* | |
26 * Return first char of filesystem type, or 0 if unknown. | |
27 */ | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
28 static char API getFSType(const char *path) |
3 | 29 { |
30 static char cache[1+26]; | |
31 char drive[3]; | |
32 ULONG unit; | |
33 char r; | |
34 | |
35 if (isalpha(path[0]) && path[1] == ':') { | |
36 unit = toupper(path[0]) - '@'; | |
37 path += 2; | |
38 } else { | |
39 return 0; | |
40 } | |
41 | |
42 if ((path[0] == '\\' || path[0] == '/') | |
43 && (path[1] == '\\' || path[1] == '/')) | |
44 return 0; | |
45 | |
46 if (cache [unit]) | |
47 return cache [unit]; | |
48 | |
49 drive[0] = '@' + unit; | |
50 drive[1] = ':'; | |
51 drive[2] = '\0'; | |
52 | |
53 r = GetDriveType(drive); | |
54 | |
55 return cache [unit] = r; | |
56 } | |
57 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
58 char * API abs_path(const char *name, char *buffer, int len) |
3 | 59 { |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
60 LPTSTR file; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
61 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
62 if(isalpha(name[0]) && name[1] == ':' && name[2] == '\0') |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
63 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
64 int drive = _getdrive(); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
65 char newdrive = toupper(name[0]); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
66 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
67 _chdrive((newdrive - 'A')+1); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
68 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
69 if(getcwd(buffer, len)) |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
70 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
71 _chdrive(drive); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
72 return buffer; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
73 } |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
74 _chdrive(drive); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
75 return NULL; |
3 | 76 } |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
77 if(GetFullPathName(name, len, buffer, &file)) |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
78 return buffer; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
79 return NULL; |
3 | 80 } |
81 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
82 DIR * API openxdir(const char *path, unsigned att_mask) |
3 | 83 { |
84 DIR *dir; | |
85 char name[MAXPATHLEN+3]; | |
86 | |
87 dir = malloc(sizeof(DIR)); | |
88 if (dir == NULL) { | |
89 errno = ENOMEM; | |
90 return NULL; | |
91 } | |
92 | |
93 strncpy(name, path, MAXPATHLEN); | |
94 name[MAXPATHLEN] = '\0'; | |
95 switch (name[strlen(name)-1]) { | |
96 default: | |
97 strcat(name, "\\"); | |
98 case '\\': | |
99 case '/': | |
100 case ':': | |
101 ; | |
102 } | |
103 strcat(name, "."); | |
104 if (!abs_path(name, dir->name, MAXPATHLEN+1)) | |
105 strcpy(dir->name, name); | |
106 if (dir->name[strlen(dir->name)-1] == '\\') | |
107 strcat(dir->name, "*"); | |
108 else | |
109 strcat(dir->name, "\\*"); | |
110 | |
111 dir->fstype = getFSType(dir->name); | |
112 dir->attrmask = att_mask | A_DIR; | |
113 | |
114 dir->count = 100; | |
184
4ec906d40ce2
FindFirstFile returns INVALID_HANDLE_VALUE on error, not NULL.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
3
diff
changeset
|
115 if((dir->handle = FindFirstFile(dir->name, &dir->data))==INVALID_HANDLE_VALUE) |
3 | 116 { |
117 free(dir); | |
118 error(rc); | |
119 return NULL; | |
120 } | |
121 | |
122 dir->number = 0; | |
123 dir->index = 0; | |
124 | |
125 return (DIR *)dir; | |
126 } | |
127 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
128 DIR * API opendir(const char *pathname) |
3 | 129 { |
130 return openxdir(pathname, 0); | |
131 } | |
132 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
133 struct dirent * API readdir(DIR *dir) |
3 | 134 { |
135 static int dummy_ino = 2; | |
136 | |
137 if (dir->number) | |
138 { | |
139 ULONG rc; | |
140 dir->count = 100; | |
141 if(!FindNextFile(dir->handle, &(dir->data))) | |
142 { | |
143 error(rc); | |
144 return NULL; | |
145 } | |
146 | |
147 dir->index = 0; | |
148 } | |
149 | |
150 strcpy(dir->entry.d_name, dir->data.cFileName); | |
151 dir->entry.d_ino = dummy_ino++; | |
152 dir->entry.d_reclen = strlen(dir->data.cFileName); | |
153 dir->entry.d_namlen = strlen(dir->data.cFileName); | |
154 dir->entry.d_size = dir->data.nFileSizeLow; | |
155 dir->entry.d_attribute = dir->data.dwFileAttributes; | |
156 #if 0 | |
157 dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite; | |
158 dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite; | |
159 #endif | |
160 | |
161 dir->number++; | |
162 dir->index++; | |
163 return &dir->entry; | |
164 } | |
165 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
166 long API telldir(DIR *dir) |
3 | 167 { |
168 return dir->number; | |
169 } | |
170 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
171 void API seekdir(DIR *dir, long off) |
3 | 172 { |
173 if (dir->number > off) { | |
174 char name[MAXPATHLEN+2]; | |
175 ULONG rc; | |
176 | |
177 FindClose(dir->handle); | |
178 | |
179 strcpy(name, dir->name); | |
180 strcat(name, "*"); | |
181 | |
182 if((dir->handle = FindFirstFile(name, &(dir->data)))==NULL) | |
183 { | |
184 error(rc); | |
185 return; | |
186 } | |
187 | |
188 dir->number = 0; | |
189 dir->index = 0; | |
190 } | |
191 | |
192 while (dir->number < off && readdir(dir)) | |
193 ; | |
194 } | |
195 | |
527
e0ea29c3d1eb
Fixed dw_window_pointer() so it works on Windows. Tried to fix the
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
260
diff
changeset
|
196 void API closedir(DIR *dir) |
3 | 197 { |
198 FindClose(dir->handle); | |
199 free(dir); | |
200 } | |
201 | |
202 /*****************************************************************************/ | |
203 | |
204 #ifdef TEST | |
205 | |
206 main(int argc, char **argv) | |
207 { | |
208 int i; | |
209 DIR *dir; | |
210 struct dirent *ep; | |
211 | |
212 for (i = 1; i < argc; ++i) { | |
213 dir = opendir(argv[i]); | |
214 if (!dir) | |
215 continue; | |
216 while (ep = readdir(dir)) | |
217 if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1])) | |
218 printf("%s%s\n", argv[i], ep->d_name); | |
219 else | |
220 printf("%s/%s\n", argv[i], ep->d_name); | |
221 closedir(dir); | |
222 } | |
223 | |
224 return 0; | |
225 } | |
226 | |
227 #endif |