Mercurial > dwindows
comparison win/dw.c @ 1250:ed2119fc210d
Initial commit of GDI+ image loader for Windows to allow use of other image formats...
not finished nor enabled by default currently but hopefully soon.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 23 Oct 2011 19:54:09 +0000 |
parents | c191a562c14a |
children | 7809be48de7d |
comparison
equal
deleted
inserted
replaced
1249:b31056c321a2 | 1250:ed2119fc210d |
---|---|
17 #include <stdlib.h> | 17 #include <stdlib.h> |
18 #include <string.h> | 18 #include <string.h> |
19 #include <stdio.h> | 19 #include <stdio.h> |
20 #include <process.h> | 20 #include <process.h> |
21 #include <time.h> | 21 #include <time.h> |
22 #ifdef GDIPLUS | |
23 #include <gdiplustypes.h> | |
24 #include <gdiplusflat.h> | |
25 #endif | |
22 #include "dw.h" | 26 #include "dw.h" |
23 #include "XBrowseForFolder.h" | 27 #include "XBrowseForFolder.h" |
24 | 28 |
25 /* | 29 /* |
26 * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA | 30 * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA |
291 | 295 |
292 FreeLibrary(hinstDll); | 296 FreeLibrary(hinstDll); |
293 } | 297 } |
294 return dwVersion; | 298 return dwVersion; |
295 } | 299 } |
300 | |
301 #ifdef GDIPLUS | |
302 /* | |
303 * List those icons that have transparency first | |
304 * GDI+ List of supported formats: BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF. | |
305 * Not sure if we should include all these or not... maybe we should add TIFF and GIF? | |
306 */ | |
307 #define NUM_EXTS 7 | |
308 char *image_exts[NUM_EXTS] = | |
309 { | |
310 ".png", | |
311 ".ico", | |
312 ".gif", | |
313 ".jpg", | |
314 ".jpeg", | |
315 ".tiff", | |
316 ".bmp" | |
317 }; | |
318 | |
319 /* Section for loading files of types besides BMP and ICO and return HBITMAP or HICON */ | |
320 GpBitmap *_dw_load_gpbitmap( char *filename ) | |
321 { | |
322 int found_ext = 0,i, wclen = (strlen(filename) + 6) * sizeof(wchar_t); | |
323 char *file = _alloca(strlen(filename) + 6); | |
324 wchar_t *wfile = _alloca(wclen); | |
325 GpBitmap *image; | |
326 | |
327 /* Try various extentions */ | |
328 for ( i = 0; i < NUM_EXTS; i++ ) | |
329 { | |
330 strcpy( file, filename ); | |
331 strcat( file, image_exts[i] ); | |
332 if ( access( file, 04 ) == 0 ) | |
333 { | |
334 /* Convert to wide format */ | |
335 MultiByteToWideChar(CP_ACP, 0, file, strlen(file), wfile, wclen); | |
336 if(GdipCreateBitmapFromFile(wfile, &image)) | |
337 return image; | |
338 } | |
339 } | |
340 return NULL; | |
341 } | |
342 | |
343 /* Try to load the appropriate image and return the HBITMAP handle */ | |
344 HBITMAP _dw_load_bitmap(char *filename, unsigned long *depth) | |
345 { | |
346 GpBitmap *bitmap = _dw_load_gpbitmap(filename); | |
347 if(bitmap) | |
348 { | |
349 HBITMAP hbm; | |
350 | |
351 if(GdipCreateHBITMAPFromBitmap(bitmap, &hbm, 0)) | |
352 { | |
353 if(depth) | |
354 { | |
355 /* TODO: Actually query the color depth here */ | |
356 *depth = 32; | |
357 } | |
358 return hbm; | |
359 } | |
360 } | |
361 return NULL; | |
362 } | |
363 | |
364 /* Try to load the appropriate image and return the HICON handle */ | |
365 HICON _dw_load_icon(char *filename) | |
366 { | |
367 GpBitmap *bitmap = _dw_load_gpbitmap(filename); | |
368 if(bitmap) | |
369 { | |
370 HICON hicon; | |
371 | |
372 if(GdipCreateHICONFromBitmap(bitmap, &hicon)) | |
373 return hicon; | |
374 } | |
375 return NULL; | |
376 } | |
377 #endif | |
296 | 378 |
297 /* This function adds a signal handler callback into the linked list. | 379 /* This function adds a signal handler callback into the linked list. |
298 */ | 380 */ |
299 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) | 381 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) |
300 { | 382 { |
3330 | 3412 |
3331 /* Associate the tooltip with the "tool" window. */ | 3413 /* Associate the tooltip with the "tool" window. */ |
3332 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); | 3414 SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti); |
3333 } | 3415 } |
3334 | 3416 |
3335 | 3417 #ifndef GDIPLUS |
3336 /* This function determines the handle for a supplied image filename | 3418 /* This function determines the handle for a supplied image filename |
3337 */ | 3419 */ |
3338 int _dw_get_image_handle(char *filename, HANDLE *icon, HBITMAP *hbitmap) | 3420 int _dw_get_image_handle(char *filename, HANDLE *icon, HBITMAP *hbitmap) |
3339 { | 3421 { |
3340 int len, windowtype = 0; | 3422 int len, windowtype = 0; |
3397 } | 3479 } |
3398 free(file); | 3480 free(file); |
3399 } | 3481 } |
3400 return windowtype; | 3482 return windowtype; |
3401 } | 3483 } |
3484 #endif | |
3402 | 3485 |
3403 /* Initialize thread local values to the defaults */ | 3486 /* Initialize thread local values to the defaults */ |
3404 void _init_thread(void) | 3487 void _init_thread(void) |
3405 { | 3488 { |
3406 COLORREF foreground = RGB(128,128,128); | 3489 COLORREF foreground = RGB(128,128,128); |
5259 int windowtype = 0, len; | 5342 int windowtype = 0, len; |
5260 | 5343 |
5261 if (!(bubble = calloc(1, sizeof(BubbleButton)))) | 5344 if (!(bubble = calloc(1, sizeof(BubbleButton)))) |
5262 return 0; | 5345 return 0; |
5263 | 5346 |
5347 #ifdef GDIPLUS | |
5348 windowtype = BS_BITMAP; | |
5349 hbitmap = _dw_load_bitmap(filename, NULL); | |
5350 #else | |
5264 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap); | 5351 windowtype = _dw_get_image_handle(filename, &icon, &hbitmap); |
5352 #endif | |
5265 | 5353 |
5266 tmp = CreateWindow( BUTTONCLASSNAME, | 5354 tmp = CreateWindow( BUTTONCLASSNAME, |
5267 "", | 5355 "", |
5268 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE, | 5356 windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE, |
5269 0,0,2000,1000, | 5357 0,0,2000,1000, |
5277 | 5365 |
5278 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble); | 5366 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble); |
5279 | 5367 |
5280 _create_tooltip(tmp, text); | 5368 _create_tooltip(tmp, text); |
5281 | 5369 |
5370 #ifndef GDIPLUS | |
5282 if (icon) | 5371 if (icon) |
5283 { | 5372 { |
5284 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_ICON,(LPARAM) icon); | 5373 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_ICON,(LPARAM) icon); |
5285 } | 5374 } |
5286 else if (hbitmap) | 5375 else |
5376 #endif | |
5377 if (hbitmap) | |
5287 { | 5378 { |
5288 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap); | 5379 SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap); |
5289 } | 5380 } |
5290 return tmp; | 5381 return tmp; |
5291 } | 5382 } |
5317 fp = fopen( file, "wb" ); | 5408 fp = fopen( file, "wb" ); |
5318 if ( fp != NULL ) | 5409 if ( fp != NULL ) |
5319 { | 5410 { |
5320 fwrite( data, 1, len, fp ); | 5411 fwrite( data, 1, len, fp ); |
5321 fclose( fp ); | 5412 fclose( fp ); |
5413 #ifdef GDIPLUS | |
5414 windowtype = BS_BITMAP; | |
5415 hbitmap = _dw_load_bitmap(file, NULL); | |
5416 #else | |
5322 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ | 5417 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ |
5323 { | 5418 { |
5324 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); | 5419 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); |
5325 windowtype = BS_BITMAP; | 5420 windowtype = BS_BITMAP; |
5326 } | 5421 } |
5327 else /* otherwise its assumed to be an ico */ | 5422 else /* otherwise its assumed to be an ico */ |
5328 { | 5423 { |
5329 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); | 5424 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); |
5330 windowtype = BS_ICON; | 5425 windowtype = BS_ICON; |
5331 } | 5426 } |
5427 #endif | |
5332 } | 5428 } |
5333 else | 5429 else |
5334 { | 5430 { |
5335 unlink( file ); | 5431 unlink( file ); |
5336 free( file ); | 5432 free( file ); |
5624 hbitmap = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED); | 5720 hbitmap = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED); |
5625 icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED); | 5721 icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED); |
5626 } | 5722 } |
5627 else if(filename) | 5723 else if(filename) |
5628 { | 5724 { |
5725 #ifdef GDIPLUS | |
5726 hbitmap = _dw_load_bitmap(filename, NULL); | |
5727 #else | |
5629 _dw_get_image_handle(filename, &icon, &hbitmap); | 5728 _dw_get_image_handle(filename, &icon, &hbitmap); |
5729 #endif | |
5630 if (icon == 0 && hbitmap == 0) | 5730 if (icon == 0 && hbitmap == 0) |
5631 return; | 5731 return; |
5632 } | 5732 } |
5633 | 5733 |
5634 if(icon) | 5734 if(icon) |
5689 fp = fopen( file, "wb" ); | 5789 fp = fopen( file, "wb" ); |
5690 if ( fp != NULL ) | 5790 if ( fp != NULL ) |
5691 { | 5791 { |
5692 fwrite( data, 1, len, fp ); | 5792 fwrite( data, 1, len, fp ); |
5693 fclose( fp ); | 5793 fclose( fp ); |
5794 #ifdef GDIPLUS | |
5795 hbitmap = _dw_load_bitmap(file, NULL); | |
5796 #else | |
5694 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ | 5797 if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */ |
5695 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); | 5798 hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); |
5696 else /* otherwise its assumed to be an ico */ | 5799 else /* otherwise its assumed to be an ico */ |
5697 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); | 5800 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); |
5801 #endif | |
5698 } | 5802 } |
5699 else | 5803 else |
5700 { | 5804 { |
5701 unlink( file ); | 5805 unlink( file ); |
5702 free( file ); | 5806 free( file ); |
7542 * DW pick the appropriate file extension. | 7646 * DW pick the appropriate file extension. |
7543 * (ICO on OS/2 or Windows, XPM on Unix) | 7647 * (ICO on OS/2 or Windows, XPM on Unix) |
7544 */ | 7648 */ |
7545 HICN API dw_icon_load_from_file(char *filename) | 7649 HICN API dw_icon_load_from_file(char *filename) |
7546 { | 7650 { |
7651 #ifdef GDIPLUS | |
7652 return _dw_load_icon(filename); | |
7653 #else | |
7547 char *file = malloc(strlen(filename) + 5); | 7654 char *file = malloc(strlen(filename) + 5); |
7548 HANDLE icon; | 7655 HANDLE icon; |
7549 | 7656 |
7550 if(!file) | 7657 if(!file) |
7551 return 0; | 7658 return 0; |
7564 } | 7671 } |
7565 } | 7672 } |
7566 icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); | 7673 icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); |
7567 free(file); | 7674 free(file); |
7568 return (HICN)icon; | 7675 return (HICN)icon; |
7676 #endif | |
7569 } | 7677 } |
7570 | 7678 |
7571 /* | 7679 /* |
7572 * Obtains an icon from data | 7680 * Obtains an icon from data |
7573 * Parameters: | 7681 * Parameters: |
7589 fp = fopen( file, "wb" ); | 7697 fp = fopen( file, "wb" ); |
7590 if ( fp != NULL ) | 7698 if ( fp != NULL ) |
7591 { | 7699 { |
7592 fwrite( data, 1, len, fp ); | 7700 fwrite( data, 1, len, fp ); |
7593 fclose( fp ); | 7701 fclose( fp ); |
7702 #ifdef GDIPLUS | |
7703 icon = _dw_load_icon(file); | |
7704 #else | |
7594 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); | 7705 icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); |
7706 #endif | |
7595 } | 7707 } |
7596 else | 7708 else |
7597 { | 7709 { |
7598 unlink( file ); | 7710 unlink( file ); |
7599 free( file ); | 7711 free( file ); |
8727 ReleaseDC(handle, hdc); | 8839 ReleaseDC(handle, hdc); |
8728 | 8840 |
8729 return pixmap; | 8841 return pixmap; |
8730 } | 8842 } |
8731 | 8843 |
8844 #ifndef GDIPLUS | |
8732 /* Read the file bitmap header ourselves... | 8845 /* Read the file bitmap header ourselves... |
8733 * apparently we can't check the depth once loaded... | 8846 * apparently we can't check the depth once loaded... |
8734 * since it seems to normalize it to our screen depth. | 8847 * since it seems to normalize it to our screen depth. |
8735 */ | 8848 */ |
8736 unsigned long _read_bitmap_header(char *file) | 8849 unsigned long _read_bitmap_header(char *file) |
8775 } | 8888 } |
8776 free(info); | 8889 free(info); |
8777 fclose(fp); | 8890 fclose(fp); |
8778 return depth; | 8891 return depth; |
8779 } | 8892 } |
8893 #endif | |
8780 | 8894 |
8781 /* | 8895 /* |
8782 * Creates a pixmap from a file. | 8896 * Creates a pixmap from a file. |
8783 * Parameters: | 8897 * Parameters: |
8784 * handle: Window handle the pixmap is associated with. | 8898 * handle: Window handle the pixmap is associated with. |
8792 { | 8906 { |
8793 HPIXMAP pixmap; | 8907 HPIXMAP pixmap; |
8794 BITMAP bm; | 8908 BITMAP bm; |
8795 HDC hdc; | 8909 HDC hdc; |
8796 ULONG cx, cy; | 8910 ULONG cx, cy; |
8797 char *file = malloc(strlen(filename) + 5); | |
8798 BITMAPINFO *info; | 8911 BITMAPINFO *info; |
8799 | 8912 #ifndef GDIPLUS |
8800 if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) | 8913 char *file; |
8801 { | 8914 #endif |
8802 if(file) | 8915 |
8803 free(file); | 8916 if (!filename || !(pixmap = calloc(1,sizeof(struct _hpixmap)))) |
8804 return NULL; | 8917 return NULL; |
8805 } | 8918 |
8806 | 8919 #ifdef GDIPLUS |
8920 pixmap->hbm = _dw_load_bitmap(filename, &pixmap->depth); | |
8921 #else | |
8922 file = _alloca(strlen(filename) + 5); | |
8807 strcpy(file, filename); | 8923 strcpy(file, filename); |
8808 | 8924 |
8809 /* check if we can read from this file (it exists and read permission) */ | 8925 /* check if we can read from this file (it exists and read permission) */ |
8810 if(access(file, 04) != 0) | 8926 if(access(file, 04) != 0) |
8811 { | 8927 { |
8817 free(file); | 8933 free(file); |
8818 return NULL; | 8934 return NULL; |
8819 } | 8935 } |
8820 } | 8936 } |
8821 | 8937 |
8822 hdc = GetDC(handle); | |
8823 | |
8824 pixmap->handle = handle; | |
8825 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); | 8938 pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); |
8826 pixmap->depth = _read_bitmap_header(file); | 8939 pixmap->depth = _read_bitmap_header(file); |
8940 #endif | |
8941 | |
8942 pixmap->handle = handle; | |
8827 | 8943 |
8828 if ( !pixmap->hbm ) | 8944 if ( !pixmap->hbm ) |
8829 { | 8945 { |
8830 free(file); | |
8831 free(pixmap); | 8946 free(pixmap); |
8832 ReleaseDC(handle, hdc); | |
8833 return NULL; | 8947 return NULL; |
8834 } | 8948 } |
8949 | |
8950 hdc = GetDC(handle); | |
8835 | 8951 |
8836 pixmap->hdc = CreateCompatibleDC( hdc ); | 8952 pixmap->hdc = CreateCompatibleDC( hdc ); |
8837 GetObject( pixmap->hbm, sizeof(bm), &bm ); | 8953 GetObject( pixmap->hbm, sizeof(bm), &bm ); |
8838 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; | 8954 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; |
8839 SelectObject( pixmap->hdc, pixmap->hbm ); | 8955 SelectObject( pixmap->hdc, pixmap->hbm ); |
8840 ReleaseDC( handle, hdc ); | 8956 ReleaseDC( handle, hdc ); |
8841 free( file ); | |
8842 pixmap->transcolor = DW_RGB_TRANSPARENT; | 8957 pixmap->transcolor = DW_RGB_TRANSPARENT; |
8843 | 8958 |
8844 return pixmap; | 8959 return pixmap; |
8845 } | 8960 } |
8846 | 8961 |
8878 fp = fopen( file, "wb" ); | 8993 fp = fopen( file, "wb" ); |
8879 if ( fp != NULL ) | 8994 if ( fp != NULL ) |
8880 { | 8995 { |
8881 fwrite( data, 1, len, fp ); | 8996 fwrite( data, 1, len, fp ); |
8882 fclose( fp ); | 8997 fclose( fp ); |
8998 #ifdef GDIPLUS | |
8999 pixmap->hbm = _dw_load_bitmap(file); | |
9000 #else | |
8883 pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); | 9001 pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); |
8884 pixmap->depth = _read_bitmap_header(file); | 9002 pixmap->depth = _read_bitmap_header(file); |
9003 #endif | |
8885 } | 9004 } |
8886 else | 9005 else |
8887 { | 9006 { |
8888 unlink( file ); | 9007 unlink( file ); |
8889 free( file ); | 9008 free( file ); |