Mercurial > hg > xemacs-beta
view lwlib/xlwgcs.c @ 5307:c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
src/ChangeLog addition:
2010-11-20 Aidan Kehoe <kehoea@parhasard.net>
* abbrev.c (Fexpand_abbrev):
* alloc.c:
* alloc.c (Fmake_list):
* alloc.c (Fmake_vector):
* alloc.c (Fmake_bit_vector):
* alloc.c (Fmake_byte_code):
* alloc.c (Fmake_string):
* alloc.c (vars_of_alloc):
* bytecode.c (UNUSED):
* bytecode.c (Fbyte_code):
* chartab.c (decode_char_table_range):
* cmds.c (Fself_insert_command):
* data.c (check_integer_range):
* data.c (Fnatnump):
* data.c (Fnonnegativep):
* data.c (Fstring_to_number):
* elhash.c (hash_table_size_validate):
* elhash.c (decode_hash_table_size):
* eval.c (Fbacktrace_frame):
* event-stream.c (lisp_number_to_milliseconds):
* event-stream.c (Faccept_process_output):
* event-stream.c (Frecent_keys):
* event-stream.c (Fdispatch_event):
* events.c (Fmake_event):
* events.c (Fevent_timestamp):
* events.c (Fevent_timestamp_lessp):
* events.h:
* events.h (struct command_builder):
* file-coding.c (gzip_putprop):
* fns.c:
* fns.c (check_sequence_range):
* fns.c (Frandom):
* fns.c (Fnthcdr):
* fns.c (Flast):
* fns.c (Fnbutlast):
* fns.c (Fbutlast):
* fns.c (Fmember):
* fns.c (Ffill):
* fns.c (Freduce):
* fns.c (replace_string_range_1):
* fns.c (Freplace):
* font-mgr.c (Ffc_pattern_get):
* frame-msw.c (msprinter_set_frame_properties):
* glyphs.c (check_valid_xbm_inline):
* indent.c (Fmove_to_column):
* intl-win32.c (mswindows_multibyte_to_unicode_putprop):
* lisp.h:
* lisp.h (ARRAY_DIMENSION_LIMIT):
* lread.c (decode_mode_1):
* mule-ccl.c (ccl_get_compiled_code):
* number.h:
* process-unix.c (unix_open_multicast_group):
* process.c (Fset_process_window_size):
* profile.c (Fstart_profiling):
* unicode.c (Funicode_to_char):
Change NATNUMP to return 1 for positive bignums; changes uses of
it and of CHECK_NATNUM appropriately, usually by checking for an
integer in an appropriate range.
Add array-dimension-limit and use it in #'make-vector,
#'make-string. Add array-total-size-limit, array-rank-limit while
we're at it, for the sake of any Common Lisp-oriented code that
uses these limits.
Rename check_int_range to check_integer_range, have it take
Lisp_Objects (and thus bignums) instead.
Remove bignum_butlast(), just set int_n to an appropriately large
integer if N is a bignum.
Accept bignums in check_sequence_range(), change the functions
that use check_sequence_range() appropriately.
Move the definition of NATNUMP() to number.h; document why it's a
reasonable name, contradicting an old comment.
tests/ChangeLog addition:
2010-11-20 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (featurep):
* automated/lisp-tests.el (wrong-type-argument):
* automated/mule-tests.el (featurep):
Check for args-out-of-range errors instead of wrong-type-argument
errors in various places when code is handed a large bignum
instead of a fixnum.
Also check for the wrong-type-argument errors when giving the same
code a non-integer value.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 20 Nov 2010 16:49:11 +0000 |
parents | 5460287a3327 |
children | 308d34e9f07d |
line wrap: on
line source
/* Tabs Widget for XEmacs. Copyright (C) 1999 Edward A. Falk This file is part of XEmacs. XEmacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Synched up with: Gcs.c 1.7 */ /* #### This code is duplicated many times within lwlib and XEmacs. It should be modularised. */ /* * Gcs.c - Utility functions to allocate GCs. * * Author: Edward A. Falk * falk@falconer.vip.best.com * * Date: Sept 29, 1998 */ /* Functions: * * GC AllocFgGC(w, fg, font) * Return a GC with foreground set as specified. * If font is None, then the returned GC is allocated with font specified * as a "don't care" value. * * GC * AllocBackgroundGC(w, font) * Return a GC with the foreground set to the widget's background color. * * GC * AllocGreyGC(w, fg, font, contrast, be_nice_to_cmap) * Widget w ; * Pixel fg ; * Font font ; * int contrast ; * int be_nice_to_cmap ; * * Return a GC suitable for rendering a widget in its "inactive" color. * Normally returns a GC with a color somewhere between the widget's * background color and the specified foreground. If font is None, then * the returned GC is allocated with font specified as "don't care". * If be_nice_to_cmap is True, the returned GC is created using a 50% * dither instead of a new color. * * * GC * AllocShadeGC(w, fg, bg, font, contrast, be_nice_to_cmap) * Widget w ; * Pixel fg, bg ; * Font font ; * int contrast ; * int be_nice_to_cmap ; * * Return a GC suitable for rendering in a shade somewhere between * bg and fg, as determined by contrast (0 = bg, 100 = fg) * If font is None, then the returned GC is allocated with * font specified as "don't care". If be_nice_to_cmap * is True, the returned GC is created using a 50% dither * instead of a new color. * * * GC * AllocTopShadowGC(w, contrast, be_nice_to_cmap) * Return a GC suitable for rendering the "top shadow" decorations of * a widget. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of white. If widget depth * is 1, this function will use a foreground color of black. * * GC * AllocBotShadowGC(w, contrast, be_nice_to_cmap) * Return a GC suitable for rendering the "bottom shadow" decorations * of a widget. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of black. * * GC * AllocArmGC(w, contrast, be_nice_to_cmap) * Return a GC suitable for rendering the "armed" decorations of a * widget. This GC would typically be used to fill in the widget's * background. Returns a GC with foreground computed from widget's * background color and contrast. If be_nice_to_cmap is True, the * returned GC will use a foreground color of black and a 50% dither. * * * void * Draw3dBox(w, x,y,wid,hgt,s, topgc, botgc) * Utility function. Draws a raised shadow box with outside dimensions * as specified by x,y,wid,hgt and shadow width specified by s. * A lowered shadow box may be generated by swapping topgc and botgc. * */ #include <config.h> #include <stdio.h> #include <X11/Xlib.h> #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #include <X11/Xmu/Drawing.h> #include <X11/Xmu/Misc.h> #include "xlwgcs.h" /* Color & GC allocation. * * Frame widgets use the following graphics contexts: * * Foreground tab label text drawn this way * Insensitive Fg foreground color greyed out. * Background frame background color * Top shadow upper-left highlight around widget * Bottom shadow lower-right highlight around widget * Arm shadow button pressed and ready to be released * * * GC's are defined as follows, depending on attributes and * window depth: * * Monochrome: * Foreground = foreground color attribute or BlackPixel() * Grey = Foreground color + 50% dither * Background = background color attribute or WhitePixel() * top shadow = foreground * bottom shadow = foreground * arm shadow = (what?) * * Color, beNiceToColormap=true: * Foreground = foreground color attribute or BlackPixel() * Grey = Foreground color + 50% dither * Background = background color attribute or WhitePixel() * top shadow = white * bottom shadow = black * arm shadow = (what?) * * Color, beNiceToColormap=false: * Foreground = foreground color attribute or BlackPixel() * Grey = (foreground color + background color)/2 * Background = background color attribute or WhitePixel() * top shadow = background * 1.2 * bottom shadow = background * .6 * arm shadow = background * .8 * * Special cases: * If background is white, ?? * if background is black, ?? * * * If the widget's background is solid white or solid black, * this code just picks some numbers. (The choice is designed * to be compatible with ThreeD interface.) */ #if NeedFunctionPrototypes static Pixmap getDitherPixmap(Widget, int contrast) ; #else static Pixmap getDitherPixmap() ; #endif /* return a GC with the specified foreground and optional font */ GC AllocFgGC(Widget w, Pixel fg, Font font) { XGCValues values ; unsigned long vmask, dcmask ; values.foreground = fg ; values.font = font ; if( font != None ) { vmask = GCForeground|GCFont ; dcmask = GCSubwindowMode|GCDashOffset| GCDashList|GCArcMode|GCBackground|GCGraphicsExposures ; } else { vmask = GCForeground ; dcmask = GCFont|GCSubwindowMode|GCDashOffset| GCDashList|GCArcMode|GCBackground|GCGraphicsExposures ; } return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ; } /* return gc with widget background color as the foreground */ GC AllocBackgroundGC(Widget w, Font font) { return AllocFgGC(w, w->core.background_pixel, font) ; } /* Allocate an "inactive" GC. Color is grey (possibly via * dither pattern). */ GC AllocGreyGC(Widget w, Pixel fg, Font font, int contrast, Bool be_nice_to_cmap) { return AllocShadeGC(w, fg, w->core.background_pixel, font, contrast, be_nice_to_cmap) ; } /* Allocate a GC somewhere between two colors. */ GC AllocShadeGC(Widget w, Pixel fg, Pixel bg, Font font, int contrast, Bool be_nice_to_cmap) { XGCValues values ; unsigned long vmask, dcmask ; values.foreground = fg ; values.background = bg ; values.font = font ; if( font != None ) { vmask = GCForeground|GCFont ; dcmask = GCSubwindowMode|GCDashOffset| GCDashList|GCArcMode|GCGraphicsExposures ; } else { vmask = GCForeground; dcmask = GCFont|GCSubwindowMode|GCDashOffset| GCDashList|GCArcMode|GCGraphicsExposures ; } if( be_nice_to_cmap || w->core.depth == 1) { if( contrast <= 5 ) values.foreground = bg ; else if( contrast >= 95 ) values.foreground = fg ; else { vmask |= GCBackground|GCStipple|GCFillStyle ; values.fill_style = FillOpaqueStippled ; values.stipple = getDitherPixmap(w, contrast) ; } return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ; } else { dcmask |= GCBackground ; values.foreground = AllocGreyPixel(w, fg, bg, contrast) ; return XtAllocateGC(w, w->core.depth, vmask, &values, 0L, dcmask) ; } } /* return top-shadow gc. */ GC AllocTopShadowGC(Widget w, int contrast, Bool be_nice_to_cmap) { Screen *scr = XtScreen (w); XGCValues values ; if( w->core.depth == 1 ) values.foreground = BlackPixelOfScreen(scr) ; else if( be_nice_to_cmap ) values.foreground = WhitePixelOfScreen(scr) ; else values.foreground = AllocShadowPixel(w, 100+contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; } /* return bottom-shadow gc. */ GC AllocBotShadowGC(Widget w, int contrast, Bool be_nice_to_cmap) { Screen *scr = XtScreen (w); XGCValues values ; if( w->core.depth == 1 || be_nice_to_cmap ) values.foreground = BlackPixelOfScreen(scr) ; else values.foreground = AllocShadowPixel(w, 100-contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; } /* return arm-shadow gc. */ GC AllocArmGC(Widget w, int contrast, Bool be_nice_to_cmap) { Screen *scr = XtScreen (w); XGCValues values ; /* Not clear exactly what we should do here. Take a look at * Xaw3d to see what they do. */ if( w->core.depth == 1 || be_nice_to_cmap ) { values.background = w->core.background_pixel ; if( values.background == BlackPixelOfScreen(scr) ) values.foreground = WhitePixelOfScreen(scr) ; else values.foreground = BlackPixelOfScreen(scr) ; values.fill_style = FillStippled ; values.stipple = XmuCreateStippledPixmap(XtScreen(w), 1L, 0L, 1) ; return XtAllocateGC(w, w->core.depth, GCForeground|GCBackground|GCStipple|GCFillStyle, &values, 0L, GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; } else { values.foreground = AllocShadowPixel(w, 100-contrast) ; return XtAllocateGC(w, w->core.depth, GCForeground, &values, 0L, GCBackground|GCFont|GCSubwindowMode|GCGraphicsExposures| GCDashOffset|GCDashList|GCArcMode) ; } } Pixel AllocShadowPixel(Widget w, int scale) { XColor get_c, set_c ; Display *dpy = XtDisplay(w) ; Screen *scr = XtScreen(w) ; Colormap cmap ; Pixel maxColor ; cmap = w->core.colormap ; get_c.pixel = w->core.background_pixel ; if( get_c.pixel == WhitePixelOfScreen(scr) || get_c.pixel == BlackPixelOfScreen(scr) ) { /* what we *ought* to do is choose gray75 as the base color, * or perhaps gray83. Instead, we choose colors that are * the same as ThreeD would choose. */ if( scale > 100 ) scale = 200 - scale ; set_c.red = set_c.green = set_c.blue = 65535*scale/100 ; } else { XQueryColor(dpy, cmap, &get_c) ; /* adjust scale so that brightest component does not * exceed 65535; otherwise hue would change. */ if( scale > 100 ) { maxColor = Max(get_c.red, Max(get_c.green, get_c.blue)) ; if( scale*maxColor > 65535*100 ) scale = 65535*100/maxColor ; } set_c.red = scale * get_c.red / 100 ; set_c.green = scale * get_c.green / 100 ; set_c.blue = scale * get_c.blue / 100 ; } set_c.flags = DoRed | DoGreen | DoBlue ; if( XAllocColor(dpy, cmap, &set_c) ) return set_c.pixel ; else if( scale > 100 ) return WhitePixelOfScreen(scr) ; else return BlackPixelOfScreen(scr) ; } /* Allocate a pixel partway between foreground and background */ Pixel AllocGreyPixel(Widget w, Pixel fg, Pixel bg, int scale) { XColor get_cf, get_cb ; Display *dpy = XtDisplay(w) ; Colormap cmap ; cmap = w->core.colormap ; get_cf.pixel = fg ; get_cb.pixel = bg ; XQueryColor(dpy, cmap, &get_cf) ; XQueryColor(dpy, cmap, &get_cb) ; return AllocGreyPixelC(w, &get_cf, &get_cb, scale) ; } /* Allocate a pixel partway between foreground and background */ Pixel AllocGreyPixelC(Widget w, XColor *fg, XColor *bg, int scale) { XColor set_c ; Display *dpy = XtDisplay(w) ; int r,g,b ; Colormap cmap = w->core.colormap ; r = (fg->red * scale + bg->red * (100-scale)) / 100 ; g = (fg->green * scale + bg->green * (100-scale)) / 100 ; b = (fg->blue * scale + bg->blue * (100-scale)) / 100 ; if( scale > 100 || scale < 0 ) /* look out for overflow */ { int minc, maxc ; maxc = Max(r, Max(g,b)) ; minc = Min(r, Min(g,b)) ; if( maxc > 65535 ) { maxc /= 16 ; r = r*(65535/16) / maxc ; g = g*(65535/16) / maxc ; b = b*(65535/16) / maxc ; } if( minc < 0 ) { r = Max(r,0) ; g = Max(g,0) ; b = Max(b,0) ; } } set_c.red = r ; set_c.green = g ; set_c.blue = b ; set_c.flags = DoRed | DoGreen | DoBlue ; (void)XAllocColor(dpy, cmap, &set_c) ; return set_c.pixel ; } /* draw a 3-d box */ void Draw3dBox(Widget w, int x, int y, int wid, int hgt, int s, GC topgc, GC botgc) { Display *dpy = XtDisplay(w) ; Window win = XtWindow(w) ; if( s == 0 ) return ; if( s == 1 ) { XDrawLine(dpy,win,botgc, x,y+hgt-1, x+wid-1,y+hgt-1) ; XDrawLine(dpy,win,botgc, x+wid-1,y, x+wid-1,y+hgt-1) ; XDrawLine(dpy,win,topgc, x,y, x,y+hgt-1) ; XDrawLine(dpy,win,topgc, x,y, x+wid-1,y) ; } else { XPoint pts[6] ; /* bottom-right shadow */ pts[0].x = x ; pts[0].y = y + hgt ; pts[1].x = s ; pts[1].y = -s ; pts[2].x = wid-2*s ; pts[2].y = 0 ; pts[3].x = 0 ; pts[3].y = -(hgt-2*s) ; pts[4].x = s ; pts[4].y = -s ; pts[5].x = 0 ; pts[5].y = hgt ; XFillPolygon(dpy,win,botgc, pts,6, Nonconvex,CoordModePrevious) ; /* top-left shadow */ pts[0].x = x ; pts[0].y = y ; pts[1].x = wid ; pts[1].y = 0 ; pts[2].x = -s ; pts[2].y = s ; pts[3].x = -wid+2*s ; pts[3].y = 0 ; pts[4].x = 0 ; pts[4].y = hgt-2*s ; pts[5].x = -s ; pts[5].y = s ; XFillPolygon(dpy,win,topgc, pts,6, Nonconvex,CoordModePrevious) ; } } static unsigned char screen0[2] = {0,0} ; static unsigned char screen25[2] = {0,0xaa} ; static unsigned char screen75[2] = {0xaa,0xff} ; static unsigned char screen100[2] = {0xff,0xff} ; static Pixmap getDitherPixmap(Widget w, int contrast) { Display *dpy = XtDisplay(w) ; Window win = XtWindow(w) ; if( contrast <= 5 ) return XCreateBitmapFromData(dpy,win, (char *)screen0, 2,2) ; else if( contrast <= 37 ) return XCreateBitmapFromData(dpy,win, (char *)screen25, 2,2) ; else if( contrast <= 62 ) return XmuCreateStippledPixmap(XtScreen(w), 1L, 0L, 1) ; else if( contrast <= 95 ) return XCreateBitmapFromData(dpy,win, (char *)screen75, 2,2) ; else return XCreateBitmapFromData(dpy,win, (char *)screen100, 2,2) ; }