Mercurial > hg > xemacs-beta
diff src/glyphs-msw.c @ 284:558f606b08ae r21-0b40
Import from CVS: tag r21-0b40
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:34:13 +0200 |
parents | c42ec1d1cded |
children | 57709be46d1b |
line wrap: on
line diff
--- a/src/glyphs-msw.c Mon Aug 13 10:33:19 2007 +0200 +++ b/src/glyphs-msw.c Mon Aug 13 10:34:13 2007 +0200 @@ -47,6 +47,10 @@ Lisp_Object Vmswindows_bitmap_file_path; static COLORREF transparent_color = RGB (1,1,1); +DEFINE_IMAGE_INSTANTIATOR_FORMAT (cursor); +Lisp_Object Qcursor; +Lisp_Object Q_resource_type, Q_resource_id; + static void mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii, enum image_instance_type type); @@ -362,10 +366,11 @@ mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, struct frame* f) { - HBITMAP mask, bmp; + HBITMAP mask; + HGDIOBJ old = NULL; HDC hcdc = FRAME_MSWINDOWS_CDC (f); BITMAPINFO* bmp_info = - xmalloc_and_zero (sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)); + xmalloc_and_zero (sizeof(BITMAPINFO) + sizeof(RGBQUAD)); int i, j; int height = IMAGE_INSTANCE_PIXMAP_HEIGHT (image); @@ -402,7 +407,7 @@ } xfree (bmp_info); - SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); + old = SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (image)); for(i=0; i<IMAGE_INSTANCE_PIXMAP_WIDTH (image); i++) { @@ -421,7 +426,7 @@ } GdiFlush(); - SelectObject(hcdc, 0); + SelectObject(hcdc, old); IMAGE_INSTANCE_MSWINDOWS_MASK (image) = mask; } @@ -448,27 +453,43 @@ struct frame* f, int newx, int newy) { - HBITMAP newbmp; + HBITMAP newbmp, newmask=NULL; HDC hcdc = FRAME_MSWINDOWS_CDC (f); HDC hdcDst = CreateCompatibleDC (hcdc); - SelectObject(hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)); + SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)); - newbmp = CreateCompatibleBitmap(hcdc, newx, newy); + newbmp = CreateCompatibleBitmap (hcdc, newx, newy); - DeleteObject( SelectObject(hdcDst, newbmp) ); + DeleteObject (SelectObject (hdcDst, newbmp) ); - if (!StretchBlt(hdcDst, 0, 0, newx, newy, - hcdc, 0, 0, - IMAGE_INSTANCE_PIXMAP_WIDTH (ii), - IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), - SRCCOPY)) + if (!StretchBlt (hdcDst, 0, 0, newx, newy, + hcdc, 0, 0, + IMAGE_INSTANCE_PIXMAP_WIDTH (ii), + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), + SRCCOPY)) { return FALSE; } - - SelectObject(hdcDst, 0); - SelectObject(hcdc, 0); + + if (IMAGE_INSTANCE_MSWINDOWS_MASK (ii)) + { + SelectObject (hcdc, IMAGE_INSTANCE_MSWINDOWS_MASK (ii)); + newmask = CreateCompatibleBitmap(hcdc, newx, newy); + SelectObject (hdcDst, newmask); + + if (!StretchBlt(hdcDst, 0, 0, newx, newy, + hcdc, 0, 0, + IMAGE_INSTANCE_PIXMAP_WIDTH (ii), + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), + SRCCOPY)) + { + return FALSE; + } + } + + SelectObject (hdcDst, 0); + SelectObject (hcdc, 0); if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)) DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii)); @@ -476,11 +497,11 @@ DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (ii)); IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = newbmp; - IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newbmp; + IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = newmask; IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = newx; IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = newy; - DeleteDC(hdcDst); + DeleteDC (hdcDst); return TRUE; } @@ -655,11 +676,11 @@ /* pick up transparencies */ else if (!strcasecmp (xpmimage.colorTable[i].c_color,"None") || - xpmimage.colorTable[i].symbolic - && - (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor") - || - !strcasecmp (xpmimage.colorTable[i].symbolic,"None"))) + (xpmimage.colorTable[i].symbolic + && + (!strcasecmp (xpmimage.colorTable[i].symbolic,"BgColor") + || + !strcasecmp (xpmimage.colorTable[i].symbolic,"None")))) { *transp=TRUE; colortbl[i]=transparent_color; @@ -709,7 +730,6 @@ BITMAPINFO* bmp_info; unsigned char* bmp_data; int bmp_bits; - COLORREF bkcolor; int nsymbols=0, transp; struct color_symbol* color_symbols=NULL; @@ -818,6 +838,246 @@ } +/********************************************************************** + * CURSORS * + **********************************************************************/ + +static void +cursor_validate (Lisp_Object instantiator) +{ + if ((NILP (find_keyword_in_vector (instantiator, Q_file)) + && + NILP (find_keyword_in_vector (instantiator, Q_resource_id))) + || + NILP (find_keyword_in_vector (instantiator, Q_resource_type))) + signal_simple_error ("Must supply :file, :resource-id and :resource-type", + instantiator); +} + +static Lisp_Object +cursor_normalize (Lisp_Object inst, Lisp_Object console_type) +{ + /* This function can call lisp */ + Lisp_Object file = Qnil; + struct gcpro gcpro1, gcpro2; + Lisp_Object alist = Qnil; + + GCPRO2 (file, alist); + + file = potential_pixmap_file_instantiator (inst, Q_file, Q_data, + console_type); + + if (CONSP (file)) /* failure locating filename */ + signal_double_file_error ("Opening pixmap file", + "no such file or directory", + Fcar (file)); + + if (NILP (file)) /* no conversion necessary */ + RETURN_UNGCPRO (inst); + + alist = tagged_vector_to_alist (inst); + + { + alist = remassq_no_quit (Q_file, alist); + alist = Fcons (Fcons (Q_file, file), alist); + } + + { + Lisp_Object result = alist_to_tagged_vector (Qcursor, alist); + free_alist (alist); + RETURN_UNGCPRO (result); + } +} + +static int +cursor_possible_dest_types (void) +{ + return IMAGE_POINTER_MASK | IMAGE_COLOR_PIXMAP_MASK; +} + +typedef struct +{ + char *name; + int resource_id; +} resource_t; + +#ifndef OCR_ICOCUR +#define OCR_ICOCUR 32647 +#define OIC_SAMPLE 32512 +#define OIC_HAND 32513 +#define OIC_QUES 32514 +#define OIC_BANG 32515 +#define OIC_NOTE 32516 +#define OIC_WINLOGO 32517 +#define LR_SHARED 0x8000 +#endif + +static CONST resource_t resource_table[] = +{ + /* bitmaps */ + { "close", OBM_CLOSE }, + { "uparrow", OBM_UPARROW }, + { "dnarrow", OBM_DNARROW }, + { "rgarrow", OBM_RGARROW }, + { "lfarrow", OBM_LFARROW }, + { "reduce", OBM_REDUCE }, + { "zoom", OBM_ZOOM }, + { "restore", OBM_RESTORE }, + { "reduced", OBM_REDUCED }, + { "zoomd", OBM_ZOOMD }, + { "restored", OBM_RESTORED }, + { "uparrowd", OBM_UPARROWD }, + { "dnarrowd", OBM_DNARROWD }, + { "rgarrowd", OBM_RGARROWD }, + { "lfarrowd", OBM_LFARROWD }, + { "mnarrow", OBM_MNARROW }, + { "combo", OBM_COMBO }, + { "uparrowi", OBM_UPARROWI }, + { "dnarrowi", OBM_DNARROWI }, + { "rgarrowi", OBM_RGARROWI }, + { "lfarrowi", OBM_LFARROWI }, + { "size", OBM_SIZE }, + { "btsize", OBM_BTSIZE }, + { "check", OBM_CHECK }, + { "cehckboxes", OBM_CHECKBOXES }, + { "btncorners" , OBM_BTNCORNERS }, + /* cursors */ + { "normal", OCR_NORMAL }, + { "ibeam", OCR_IBEAM }, + { "wait", OCR_WAIT }, + { "cross", OCR_CROSS }, + { "up", OCR_UP }, + /* { "icon", OCR_ICON }, */ + { "sizenwse", OCR_SIZENWSE }, + { "sizenesw", OCR_SIZENESW }, + { "sizewe", OCR_SIZEWE }, + { "sizens", OCR_SIZENS }, + { "sizeall", OCR_SIZEALL }, + /* { "icour", OCR_ICOCUR }, */ + { "no", OCR_NO }, + /* icons */ + { "sample", OIC_SAMPLE }, + { "hand", OIC_HAND }, + { "ques", OIC_QUES }, + { "bang", OIC_BANG }, + { "note", OIC_NOTE }, + { "winlogo", OIC_WINLOGO }, + {0} +}; + +static int cursor_name_to_resource (Lisp_Object name) +{ + CONST resource_t* res = resource_table; + + if (INTP (name)) + { + return XINT (name); + } + else if (!STRINGP (name)) + { + signal_simple_error ("invalid resource identifier", name); + } + + do { + if (!strcasecmp ((char*)res->name, XSTRING_DATA (name))) + return res->resource_id; + } while ((++res)->name); + return 0; +} + +static void +cursor_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, + Lisp_Object pointer_fg, Lisp_Object pointer_bg, + int dest_mask, Lisp_Object domain) +{ + struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); + unsigned int type = 0; + HANDLE himage = NULL; + LPCTSTR resid=0; + int iitype=0; + Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii); + + Lisp_Object file = find_keyword_in_vector (instantiator, Q_file); + Lisp_Object resource_type = find_keyword_in_vector (instantiator, + Q_resource_type); + Lisp_Object resource_id = find_keyword_in_vector (instantiator, + Q_resource_id); + + if (!DEVICE_MSWINDOWS_P (XDEVICE (device))) + signal_simple_error ("Not an mswindows device", device); + + assert (!NILP (resource_type) && !NILP (resource_id)); + + /* check the resource type */ + if (!SYMBOLP (resource_type)) + { + signal_simple_error ("invalid resource type", resource_type); + } + if (!strcmp ((char *) string_data (XSYMBOL (resource_type)->name), + "bitmap")) + type = IMAGE_BITMAP; + else if (!strcmp ((char *) string_data (XSYMBOL (resource_type)->name), + "cursor")) + type = IMAGE_CURSOR; + else if (!strcmp ((char *) string_data (XSYMBOL (resource_type)->name), + "icon")) + type = IMAGE_ICON; + else + signal_simple_error ("invalid resource type", resource_type); + + if (dest_mask & IMAGE_POINTER_MASK && type == IMAGE_CURSOR) + iitype = IMAGE_POINTER; + else if (dest_mask & IMAGE_COLOR_PIXMAP_MASK) + iitype = IMAGE_COLOR_PIXMAP; + else + incompatible_image_types (instantiator, dest_mask, + IMAGE_COLOR_PIXMAP_MASK | IMAGE_POINTER_MASK); + + if (!NILP (file)) + resid = (LPCTSTR)XSTRING_DATA (file); + else if (!(resid = MAKEINTRESOURCE(cursor_name_to_resource (resource_id)))) + signal_simple_error ("invalid resource id", resource_id); + + /* load the image */ + if (!(himage = LoadImage (NULL, resid, type, 0, 0, + LR_CREATEDIBSECTION | LR_DEFAULTSIZE | + LR_SHARED | + (!NILP (file) ? LR_LOADFROMFILE : 0)))) + { + signal_simple_error ("cannot load image", instantiator); + } + + mswindows_initialize_dibitmap_image_instance (ii, iitype); + + IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file; + IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = (type==IMAGE_BITMAP ? himage : NULL); + IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL; + IMAGE_INSTANCE_MSWINDOWS_ICON (ii) = (type!=IMAGE_BITMAP ? himage : NULL); + IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = + (type == IMAGE_CURSOR ? SM_CXCURSOR : SM_CXICON); + IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = + (type == IMAGE_CURSOR ? SM_CYCURSOR : SM_CYICON); + IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = 0; + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii), 0); + XSETINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii), 0); +} + +void +check_valid_symbol (Lisp_Object data) +{ + CHECK_SYMBOL (data); +} + +void +check_valid_string_or_int (Lisp_Object data) +{ + if (!INTP (data)) + CHECK_STRING (data); + else + CHECK_INT (data); +} + + /************************************************************************/ /* image instance methods */ /************************************************************************/ @@ -935,6 +1195,8 @@ void syms_of_glyphs_mswindows (void) { + defkeyword (&Q_resource_id, ":resource-id"); + defkeyword (&Q_resource_type, ":resource-type"); } void @@ -967,12 +1229,24 @@ IIFORMAT_VALID_KEYWORD (bmp, Q_data, check_valid_string); IIFORMAT_VALID_KEYWORD (bmp, Q_file, check_valid_string); + + INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor, "cursor"); + + IIFORMAT_HAS_METHOD (cursor, validate); + IIFORMAT_HAS_METHOD (cursor, normalize); + IIFORMAT_HAS_METHOD (cursor, possible_dest_types); + IIFORMAT_HAS_METHOD (cursor, instantiate); + + IIFORMAT_VALID_KEYWORD (cursor, Q_resource_type, check_valid_symbol); + IIFORMAT_VALID_KEYWORD (cursor, Q_resource_id, check_valid_string_or_int); + IIFORMAT_VALID_KEYWORD (cursor, Q_file, check_valid_string); } void vars_of_glyphs_mswindows (void) { Fprovide (Qbmp); + Fprovide (Qcursor); DEFVAR_LISP ("mswindows-bitmap-file-path", &Vmswindows_bitmap_file_path /* A list of the directories in which mswindows bitmap files may be found. This is used by the `make-image-instance' function.