Mercurial > dwindows
annotate win/dirent.c @ 1568:625c4d1555fe
Added code to calculate the container size on OS/2.
With no items this can only detect the title height and splitbar position.
With items in the container this should function properly.
Will try to figure out the title widths with no items.
Also some more formatting cleanups.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sat, 21 Jan 2012 03:13:32 +0000 |
parents | 412af8059331 |
children | 6baf177f335c |
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> |
1362
412af8059331
Attempt to get it building with Mingw again... builds but crashes.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
572
diff
changeset
|
10 #include <direct.h> |
3 | 11 |
12 #define error(rc) errno = 255 | |
13 | |
14 struct _dirdescr { | |
15 HANDLE handle; /* DosFindFirst handle */ | |
16 char fstype; /* filesystem type */ | |
17 long count; /* valid entries in <ffbuf> */ | |
18 long number; /* absolute number of next entry */ | |
19 int index; /* relative number of next entry */ | |
20 char name[MAXPATHLEN+3]; /* directory name */ | |
21 unsigned attrmask; /* attribute mask for seekdir */ | |
22 struct dirent entry; /* buffer for directory entry */ | |
23 WIN32_FIND_DATA data; | |
24 }; | |
25 | |
26 /* | |
27 * Return first char of filesystem type, or 0 if unknown. | |
28 */ | |
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
|
29 static char API getFSType(const char *path) |
3 | 30 { |
31 static char cache[1+26]; | |
32 char drive[3]; | |
33 ULONG unit; | |
34 char r; | |
35 | |
36 if (isalpha(path[0]) && path[1] == ':') { | |
37 unit = toupper(path[0]) - '@'; | |
38 path += 2; | |
39 } else { | |
40 return 0; | |
41 } | |
42 | |
43 if ((path[0] == '\\' || path[0] == '/') | |
44 && (path[1] == '\\' || path[1] == '/')) | |
45 return 0; | |
46 | |
47 if (cache [unit]) | |
48 return cache [unit]; | |
49 | |
50 drive[0] = '@' + unit; | |
51 drive[1] = ':'; | |
52 drive[2] = '\0'; | |
53 | |
54 r = GetDriveType(drive); | |
55 | |
56 return cache [unit] = r; | |
57 } | |
58 | |
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
|
59 char * API abs_path(const char *name, char *buffer, int len) |
3 | 60 { |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
61 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
|
62 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
63 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
|
64 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
65 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
|
66 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
|
67 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
68 _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
|
69 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
70 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
|
71 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
72 _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
|
73 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
|
74 } |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
75 _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
|
76 return NULL; |
3 | 77 } |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
78 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
|
79 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
|
80 return NULL; |
3 | 81 } |
82 | |
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
|
83 DIR * API openxdir(const char *path, unsigned att_mask) |
3 | 84 { |
85 DIR *dir; | |
86 char name[MAXPATHLEN+3]; | |
87 | |
88 dir = malloc(sizeof(DIR)); | |
89 if (dir == NULL) { | |
90 errno = ENOMEM; | |
91 return NULL; | |
92 } | |
93 | |
94 strncpy(name, path, MAXPATHLEN); | |
95 name[MAXPATHLEN] = '\0'; | |
96 switch (name[strlen(name)-1]) { | |
97 default: | |
98 strcat(name, "\\"); | |
99 case '\\': | |
100 case '/': | |
101 case ':': | |
102 ; | |
103 } | |
104 strcat(name, "."); | |
105 if (!abs_path(name, dir->name, MAXPATHLEN+1)) | |
106 strcpy(dir->name, name); | |
107 if (dir->name[strlen(dir->name)-1] == '\\') | |
108 strcat(dir->name, "*"); | |
109 else | |
110 strcat(dir->name, "\\*"); | |
111 | |
112 dir->fstype = getFSType(dir->name); | |
113 dir->attrmask = att_mask | A_DIR; | |
114 | |
115 dir->count = 100; | |
184
4ec906d40ce2
FindFirstFile returns INVALID_HANDLE_VALUE on error, not NULL.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
3
diff
changeset
|
116 if((dir->handle = FindFirstFile(dir->name, &dir->data))==INVALID_HANDLE_VALUE) |
3 | 117 { |
118 free(dir); | |
119 error(rc); | |
120 return NULL; | |
121 } | |
122 | |
123 dir->number = 0; | |
124 dir->index = 0; | |
125 | |
126 return (DIR *)dir; | |
127 } | |
128 | |
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
|
129 DIR * API opendir(const char *pathname) |
3 | 130 { |
131 return openxdir(pathname, 0); | |
132 } | |
133 | |
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
|
134 struct dirent * API readdir(DIR *dir) |
3 | 135 { |
136 static int dummy_ino = 2; | |
137 | |
138 if (dir->number) | |
139 { | |
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 | |
176 FindClose(dir->handle); | |
177 | |
178 strcpy(name, dir->name); | |
179 strcat(name, "*"); | |
180 | |
181 if((dir->handle = FindFirstFile(name, &(dir->data)))==NULL) | |
182 { | |
183 error(rc); | |
184 return; | |
185 } | |
186 | |
187 dir->number = 0; | |
188 dir->index = 0; | |
189 } | |
190 | |
191 while (dir->number < off && readdir(dir)) | |
192 ; | |
193 } | |
194 | |
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
|
195 void API closedir(DIR *dir) |
3 | 196 { |
197 FindClose(dir->handle); | |
198 free(dir); | |
199 } | |
200 | |
201 /*****************************************************************************/ | |
202 | |
203 #ifdef TEST | |
204 | |
205 main(int argc, char **argv) | |
206 { | |
207 int i; | |
208 DIR *dir; | |
209 struct dirent *ep; | |
210 | |
211 for (i = 1; i < argc; ++i) { | |
212 dir = opendir(argv[i]); | |
213 if (!dir) | |
214 continue; | |
215 while (ep = readdir(dir)) | |
216 if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1])) | |
217 printf("%s%s\n", argv[i], ep->d_name); | |
218 else | |
219 printf("%s/%s\n", argv[i], ep->d_name); | |
220 closedir(dir); | |
221 } | |
222 | |
223 return 0; | |
224 } | |
225 | |
226 #endif |