80ba448abbd196e8c585e7002a82d62fc57ffe0c
[gpgol.git] / src / common.c
1 /* common.c 
2  *      Copyright (C) 2005 g10 Code GmbH
3  *
4  * This file is part of GPGol.
5  *
6  * GPGol is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 
9  * of the License, or (at your option) any later version.
10  *  
11  * GPGol is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with GPGol; if not, write to the Free Software Foundation, 
18  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
19  */
20 #include <windows.h>
21 #include <time.h>
22
23 #include "gpgme.h"
24 #include "intern.h"
25
26 HINSTANCE glob_hinst = NULL;
27
28 void
29 set_global_hinstance (HINSTANCE hinst)
30 {
31     glob_hinst = hinst;
32 }
33
34 /* Center the given window with the desktop window as the
35    parent window. */
36 void
37 center_window (HWND childwnd, HWND style) 
38 {     
39     HWND parwnd;
40     RECT rchild, rparent;    
41     HDC hdc;
42     int wchild, hchild, wparent, hparent;
43     int wscreen, hscreen, xnew, ynew;
44     int flags = SWP_NOSIZE | SWP_NOZORDER;
45
46     parwnd = GetDesktopWindow ();
47     GetWindowRect (childwnd, &rchild);     
48     wchild = rchild.right - rchild.left;     
49     hchild = rchild.bottom - rchild.top;
50
51     GetWindowRect (parwnd, &rparent);     
52     wparent = rparent.right - rparent.left;     
53     hparent = rparent.bottom - rparent.top;      
54     
55     hdc = GetDC (childwnd);     
56     wscreen = GetDeviceCaps (hdc, HORZRES);     
57     hscreen = GetDeviceCaps (hdc, VERTRES);     
58     ReleaseDC (childwnd, hdc);      
59     xnew = rparent.left + ((wparent - wchild) / 2);     
60     if (xnew < 0)
61         xnew = 0;
62     else if ((xnew+wchild) > wscreen) 
63         xnew = wscreen - wchild;
64     ynew = rparent.top  + ((hparent - hchild) / 2);
65     if (ynew < 0)
66         ynew = 0;
67     else if ((ynew+hchild) > hscreen)
68         ynew = hscreen - hchild;
69     if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
70         flags = SWP_NOMOVE | SWP_NOSIZE;
71     SetWindowPos (childwnd, style? style : NULL, xnew, ynew, 0, 0, flags);
72 }
73
74
75
76 /* Return a filename to be used for saving an attachment. Returns a
77    malloced string on success. HWND is the current Window and SRCNAME
78    the filename to be used as suggestion.  On error (i.e. cancel) NULL
79    is returned. */
80 char *
81 get_save_filename (HWND root, const char *srcname)
82                                      
83 {
84   char filter[] = "All Files (*.*)\0*.*\0\0";
85   char fname[MAX_PATH+1];
86   OPENFILENAME ofn;
87
88   memset (fname, 0, sizeof (fname));
89   strncpy (fname, srcname, MAX_PATH-1);
90   fname[MAX_PATH] = 0;  
91   
92
93   memset (&ofn, 0, sizeof (ofn));
94   ofn.lStructSize = sizeof (ofn);
95   ofn.hwndOwner = root;
96   ofn.lpstrFile = fname;
97   ofn.nMaxFile = MAX_PATH;
98   ofn.lpstrFileTitle = NULL;
99   ofn.nMaxFileTitle = 0;
100   ofn.Flags |= OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
101   ofn.lpstrTitle = "GPG - Save decrypted attachment";
102   ofn.lpstrFilter = filter;
103
104   if (GetSaveFileName (&ofn))
105     return xstrdup (fname);
106   return NULL;
107 }
108
109
110 void
111 out_of_core (void)
112 {
113     MessageBox (NULL, "Out of core!", "Fatal Error", MB_OK);
114     abort ();
115 }
116
117 void*
118 xmalloc (size_t n)
119 {
120     void *p = malloc (n);
121     if (!p)
122         out_of_core ();
123     return p;
124 }
125
126 void*
127 xcalloc (size_t m, size_t n)
128 {
129     void *p = calloc (m, n);
130     if (!p)
131         out_of_core ();
132     return p;
133 }
134
135 char*
136 xstrdup (const char *s)
137 {
138     char *p = xmalloc (strlen (s)+1);
139     strcpy (p, s);
140     return p;
141 }
142
143 void
144 xfree (void *p)
145 {
146     if (p)
147         free (p);
148 }
149
150
151 /* This is a helper function to load a Windows function from either of
152    one DLLs. */
153 HRESULT
154 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
155 {
156   static int initialized;
157   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
158
159   if (!initialized)
160     {
161       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
162       void *handle;
163       int i;
164
165       initialized = 1;
166
167       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
168         {
169           handle = LoadLibrary (dllnames[i]);
170           if (handle)
171             {
172               func = (HRESULT (WINAPI *)(HWND,int,HANDLE,DWORD,LPSTR))
173                      GetProcAddress (handle, "SHGetFolderPathA");
174               if (!func)
175                 {
176                   FreeLibrary (handle);
177                   handle = NULL;
178                 }
179             }
180         }
181     }
182
183   if (func)
184     return func (a,b,c,d,e);
185   else
186     return -1;
187 }
188
189
190 /* Return a malloced string encoded in UTF-8 from the wide char input
191    string STRING.  Caller must xfree this value. On failure returns
192    NULL; caller may use GetLastError to get the actual error number.
193    The result of calling this function with STRING set to NULL is not
194    defined. */
195 char *
196 wchar_to_utf8 (const wchar_t *string)
197 {
198   int n;
199   char *result;
200
201   /* Note, that CP_UTF8 is not defined in Windows versions earlier
202      than NT.*/
203   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
204   if (n < 0)
205     return NULL;
206
207   result = xmalloc (n+1);
208   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
209   if (n < 0)
210     {
211       xfree (result);
212       return NULL;
213     }
214   return result;
215 }
216
217
218 /* Same as above, but only convert the first LEN wchars.  */
219 char *
220 wchar_to_utf8_2 (const wchar_t *string, size_t len)
221 {
222   int n;
223   char *result;
224
225   /* Note, that CP_UTF8 is not defined in Windows versions earlier
226      than NT.*/
227   n = WideCharToMultiByte (CP_UTF8, 0, string, len, NULL, 0, NULL, NULL);
228   if (n < 0)
229     return NULL;
230
231   result = xmalloc (n+1);
232   n = WideCharToMultiByte (CP_UTF8, 0, string, len, result, n, NULL, NULL);
233   if (n < 0)
234     {
235       xfree (result);
236       return NULL;
237     }
238   return result;
239 }
240
241 /* Return a malloced wide char string from an UTF-8 encoded input
242    string STRING.  Caller must xfree this value. On failure returns
243    NULL; caller may use GetLastError to get the actual error number.
244    The result of calling this function with STRING set to NULL is not
245    defined. */
246 wchar_t *
247 utf8_to_wchar (const char *string)
248 {
249   int n;
250   wchar_t *result;
251
252   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
253   if (n < 0)
254     return NULL;
255
256   result = xmalloc ((n+1) * sizeof *result);
257   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
258   if (n < 0)
259     {
260       xfree (result);
261       return NULL;
262     }
263   return result;
264 }
265
266
267 /* Same as above but convert only the first LEN characters.  STRING
268    must be at least LEN characters long. */
269 wchar_t *
270 utf8_to_wchar2 (const char *string, size_t len)
271 {
272   int n;
273   wchar_t *result;
274
275   n = MultiByteToWideChar (CP_UTF8, 0, string, len, NULL, 0);
276   if (n < 0)
277     return NULL;
278
279   result = xmalloc ((n+1) * sizeof *result);
280   n = MultiByteToWideChar (CP_UTF8, 0, string, len, result, n);
281   if (n < 0)
282     {
283       xfree (result);
284       return NULL;
285     }
286   result[n] = 0;
287   return result;
288 }
289
290
291 /* Assume STRING is a Latin-1 encoded and convert it to utf-8.
292    Returns a newly malloced UTF-8 string. */
293 char *
294 latin1_to_utf8 (const char *string)
295 {
296   const char *s;
297   char *buffer, *p;
298   size_t n;
299
300   for (s=string, n=0; *s; s++) 
301     {
302       n++;
303       if (*s & 0x80)
304         n++;
305     }
306   buffer = xmalloc (n + 1);
307   for (s=string, p=buffer; *s; s++)
308     {
309       if (*s & 0x80)
310         {
311           *p++ = 0xc0 | ((*s >> 6) & 3);
312           *p++ = 0x80 | (*s & 0x3f);
313         }
314       else
315         *p++ = *s;
316     }
317   *p = 0;
318   return buffer;
319 }
320
321
322 /* Strip off trailing white spaces from STRING.  Returns STRING. */
323 char *
324 trim_trailing_spaces (char *string)
325 {
326   char *p, *mark;
327
328   for (mark=NULL, p=string; *p; p++)
329     {
330       if (strchr (" \t\r\n", *p ))
331         {
332           if (!mark)
333             mark = p;
334         }
335         else
336           mark = NULL;
337     }
338
339   if (mark)
340     *mark = 0;
341   return string;
342 }