comparison src/frame.c @ 50357:e5a09c97e444

Include blockinput.h. (Vx_resource_name, Vx_resource_class, Qx_frame_parameter) (Qx_resource_name, Qface_set_after_frame_default): Define vars here. (Qauto_raise, Qauto_lower, ...): Define all frame parameter related vars here. (struct frame_parm_table, frame_parms): New table for describing frame parameters and their associated Q-variable. The order of the parameters corresponds to the sequence of the frame_parm_handlers table in redisplay_interface. (x_fullscreen_move, x_set_frame_parameters) (x_report_frame_params, x_set_fullscreen, x_set_line_spacing) (x_set_screen_gamma, x_set_font, x_set_fringe_width) (x_set_border_width, x_set_internal_border_width, x_set_visibility) (x_set_autoraise, x_set_autolower, x_set_unsplittable) (x_set_vertical_scroll_bars, x_set_scroll_bar_width, x_icon_type): Generic functions for processing of frame parameters. (validate_x_resource_name, xrdb_get_resource, Fx_get_resource) (display_x_get_resource, x_get_resource_string): Functions for generic access to X resources. (x_get_arg, x_frame_get_arg, x_frame_get_and_record_arg) (x_default_parameter, Fx_parse_geometry): Functions for generic access to frame parameters. (x_figure_window_size): Generic calculation of frame size. Fixed to add space needed for tool bar. Also setup size_hint_flags. (syms_of_frame): Intern and staticpro frame parameter variables. Defvar_lisp Vx_resource_class and Vx_resource_name here. Defsubr Sx_get_resource and Sx_parse_geometry.
author Kim F. Storm <storm@cua.dk>
date Mon, 31 Mar 2003 20:33:58 +0000
parents 23a1cea22d13
children 6defa3317421
comparison
equal deleted inserted replaced
50356:933b5f877c91 50357:e5a09c97e444
39 #include "keyboard.h" 39 #include "keyboard.h"
40 #include "frame.h" 40 #include "frame.h"
41 #ifdef HAVE_WINDOW_SYSTEM 41 #ifdef HAVE_WINDOW_SYSTEM
42 #include "fontset.h" 42 #include "fontset.h"
43 #endif 43 #endif
44 #include "blockinput.h"
44 #include "termhooks.h" 45 #include "termhooks.h"
45 #include "dispextern.h" 46 #include "dispextern.h"
46 #include "window.h" 47 #include "window.h"
47 #ifdef MSDOS 48 #ifdef MSDOS
48 #include "msdos.h" 49 #include "msdos.h"
49 #include "dosfns.h" 50 #include "dosfns.h"
50 #endif 51 #endif
51 52
52 Lisp_Object Qframep; 53
53 Lisp_Object Qframe_live_p; 54 /* The name we're using in resource queries. Most often "emacs". */
54 Lisp_Object Qheight; 55
55 Lisp_Object Qicon; 56 Lisp_Object Vx_resource_name;
56 Lisp_Object Qminibuffer; 57
57 Lisp_Object Qmodeline; 58 /* The application class we're using in resource queries.
58 Lisp_Object Qname; 59 Normally "Emacs". */
60
61 Lisp_Object Vx_resource_class;
62
63
64 Lisp_Object Qframep, Qframe_live_p;
65 Lisp_Object Qicon, Qmodeline;
59 Lisp_Object Qonly; 66 Lisp_Object Qonly;
60 Lisp_Object Qunsplittable; 67 Lisp_Object Qx, Qw32, Qmac, Qpc;
61 Lisp_Object Qmenu_bar_lines;
62 Lisp_Object Qtool_bar_lines;
63 Lisp_Object Qwidth;
64 Lisp_Object Qx;
65 Lisp_Object Qw32;
66 Lisp_Object Qpc;
67 Lisp_Object Qmac;
68 Lisp_Object Qvisible; 68 Lisp_Object Qvisible;
69 Lisp_Object Qbuffer_predicate;
70 Lisp_Object Qbuffer_list;
71 Lisp_Object Qtitle;
72 Lisp_Object Qdisplay_type; 69 Lisp_Object Qdisplay_type;
73 Lisp_Object Qbackground_mode; 70 Lisp_Object Qbackground_mode;
74 Lisp_Object Qinhibit_default_face_x_resources; 71 Lisp_Object Qinhibit_default_face_x_resources;
75 Lisp_Object Qleft_fringe; 72
76 Lisp_Object Qright_fringe; 73 Lisp_Object Qx_frame_parameter;
74 Lisp_Object Qx_resource_name;
75
76 /* Frame parameters (set or reported). */
77
78 Lisp_Object Qauto_raise, Qauto_lower;
79 Lisp_Object Qborder_color, Qborder_width;
80 Lisp_Object Qcursor_color, Qcursor_type;
81 Lisp_Object Qgeometry; /* Not used */
82 Lisp_Object Qheight, Qwidth;
83 Lisp_Object Qleft, Qright;
84 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
85 Lisp_Object Qinternal_border_width;
86 Lisp_Object Qmouse_color;
87 Lisp_Object Qminibuffer;
88 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
89 Lisp_Object Qvisibility;
90 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
91 Lisp_Object Qscreen_gamma;
92 Lisp_Object Qline_spacing;
93 Lisp_Object Quser_position, Quser_size;
94 Lisp_Object Qwait_for_wm;
95 Lisp_Object Qwindow_id;
96 #ifdef HAVE_X_WINDOWS
97 Lisp_Object Qouter_window_id;
98 #endif
99 Lisp_Object Qparent_id;
100 Lisp_Object Qtitle, Qname;
101 Lisp_Object Qunsplittable;
102 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
103 Lisp_Object Qleft_fringe, Qright_fringe;
104 Lisp_Object Qbuffer_predicate, Qbuffer_list;
77 Lisp_Object Qtty_color_mode; 105 Lisp_Object Qtty_color_mode;
106
107 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
108
109 Lisp_Object Qface_set_after_frame_default;
110
78 111
79 Lisp_Object Vterminal_frame; 112 Lisp_Object Vterminal_frame;
80 Lisp_Object Vdefault_frame_alist; 113 Lisp_Object Vdefault_frame_alist;
81 Lisp_Object Vmouse_position_function; 114 Lisp_Object Vmouse_position_function;
82 Lisp_Object Vmouse_highlight; 115 Lisp_Object Vmouse_highlight;
2435 2468
2436 return Qt; 2469 return Qt;
2437 } 2470 }
2438 2471
2439 2472
2473 /***********************************************************************
2474 Frame Parameters
2475 ***********************************************************************/
2476
2477 /* Connect the frame-parameter names for X frames
2478 to the ways of passing the parameter values to the window system.
2479
2480 The name of a parameter, as a Lisp symbol,
2481 has an `x-frame-parameter' property which is an integer in Lisp
2482 that is an index in this table. */
2483
2484 struct frame_parm_table {
2485 char *name;
2486 Lisp_Object *variable;
2487 };
2488
2489 static struct frame_parm_table frame_parms[] =
2490 {
2491 {"auto-raise", &Qauto_raise},
2492 {"auto-lower", &Qauto_lower},
2493 {"background-color", 0},
2494 {"border-color", &Qborder_color},
2495 {"border-width", &Qborder_width},
2496 {"cursor-color", &Qcursor_color},
2497 {"cursor-type", &Qcursor_type},
2498 {"font", 0},
2499 {"foreground-color", 0},
2500 {"icon-name", &Qicon_name},
2501 {"icon-type", &Qicon_type},
2502 {"internal-border-width", &Qinternal_border_width},
2503 {"menu-bar-lines", &Qmenu_bar_lines},
2504 {"mouse-color", &Qmouse_color},
2505 {"name", &Qname},
2506 {"scroll-bar-width", &Qscroll_bar_width},
2507 {"title", &Qtitle},
2508 {"unsplittable", &Qunsplittable},
2509 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2510 {"visibility", &Qvisibility},
2511 {"tool-bar-lines", &Qtool_bar_lines},
2512 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2513 {"scroll-bar-background", &Qscroll_bar_background},
2514 {"screen-gamma", &Qscreen_gamma},
2515 {"line-spacing", &Qline_spacing},
2516 {"left-fringe", &Qleft_fringe},
2517 {"right-fringe", &Qright_fringe},
2518 {"wait-for-wm", &Qwait_for_wm},
2519 {"fullscreen", &Qfullscreen},
2520 };
2521
2522 #ifdef HAVE_WINDOW_SYSTEM
2523
2524 extern Lisp_Object Qbox;
2525 extern Lisp_Object Qtop;
2526
2527 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2528 wanted positions of the WM window (not emacs window).
2529 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2530 window (FRAME_X_WINDOW).
2531 */
2532
2533 void
2534 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2535 struct frame *f;
2536 int *width;
2537 int *height;
2538 int *top_pos;
2539 int *left_pos;
2540 {
2541 int newwidth = f->width, newheight = f->height;
2542
2543 *top_pos = FRAME_X_OUTPUT (f)->top_pos;
2544 *left_pos = FRAME_X_OUTPUT (f)->left_pos;
2545
2546 if (FRAME_X_OUTPUT (f)->want_fullscreen & FULLSCREEN_HEIGHT)
2547 {
2548 int ph;
2549
2550 ph = FRAME_X_DISPLAY_INFO (f)->height;
2551 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
2552 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
2553 - FRAME_X_OUTPUT (f)->y_pixels_diff;
2554 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
2555 *top_pos = 0;
2556 }
2557
2558 if (FRAME_X_OUTPUT (f)->want_fullscreen & FULLSCREEN_WIDTH)
2559 {
2560 int pw;
2561
2562 pw = FRAME_X_DISPLAY_INFO (f)->width;
2563 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
2564 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
2565 - FRAME_X_OUTPUT (f)->x_pixels_diff;
2566 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
2567 *left_pos = 0;
2568 }
2569
2570 *width = newwidth;
2571 *height = newheight;
2572 }
2573
2574
2575 /* Really try to move where we want to be in case of fullscreen. Some WMs
2576 moves the window where we tell them. Some (mwm, twm) moves the outer
2577 window manager window there instead.
2578 Try to compensate for those WM here. */
2579
2580 static void
2581 x_fullscreen_move (f, new_top, new_left)
2582 struct frame *f;
2583 int new_top;
2584 int new_left;
2585 {
2586 if (new_top != FRAME_X_OUTPUT (f)->top_pos
2587 || new_left != FRAME_X_OUTPUT (f)->left_pos)
2588 {
2589 int move_x = new_left;
2590 int move_y = new_top;
2591
2592 #ifdef HAVE_X_WINDOWS
2593 move_x += FRAME_X_OUTPUT (f)->x_pixels_outer_diff;
2594 move_y += FRAME_X_OUTPUT (f)->y_pixels_outer_diff;
2595 #endif
2596
2597 FRAME_X_OUTPUT (f)->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
2598 x_set_offset (f, move_x, move_y, 1);
2599 }
2600 }
2601
2602 /* Change the parameters of frame F as specified by ALIST.
2603 If a parameter is not specially recognized, do nothing special;
2604 otherwise call the `x_set_...' function for that parameter.
2605 Except for certain geometry properties, always call store_frame_param
2606 to store the new value in the parameter alist. */
2607
2608 void
2609 x_set_frame_parameters (f, alist)
2610 FRAME_PTR f;
2611 Lisp_Object alist;
2612 {
2613 Lisp_Object tail;
2614
2615 /* If both of these parameters are present, it's more efficient to
2616 set them both at once. So we wait until we've looked at the
2617 entire list before we set them. */
2618 int width, height;
2619
2620 /* Same here. */
2621 Lisp_Object left, top;
2622
2623 /* Same with these. */
2624 Lisp_Object icon_left, icon_top;
2625
2626 /* Record in these vectors all the parms specified. */
2627 Lisp_Object *parms;
2628 Lisp_Object *values;
2629 int i, p;
2630 int left_no_change = 0, top_no_change = 0;
2631 int icon_left_no_change = 0, icon_top_no_change = 0;
2632 int fullscreen_is_being_set = 0;
2633
2634 struct gcpro gcpro1, gcpro2;
2635
2636 i = 0;
2637 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2638 i++;
2639
2640 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2641 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2642
2643 /* Extract parm names and values into those vectors. */
2644
2645 i = 0;
2646 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2647 {
2648 Lisp_Object elt;
2649
2650 elt = Fcar (tail);
2651 parms[i] = Fcar (elt);
2652 values[i] = Fcdr (elt);
2653 i++;
2654 }
2655 /* TAIL and ALIST are not used again below here. */
2656 alist = tail = Qnil;
2657
2658 GCPRO2 (*parms, *values);
2659 gcpro1.nvars = i;
2660 gcpro2.nvars = i;
2661
2662 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2663 because their values appear in VALUES and strings are not valid. */
2664 top = left = Qunbound;
2665 icon_left = icon_top = Qunbound;
2666
2667 /* Provide default values for HEIGHT and WIDTH. */
2668 if (FRAME_NEW_WIDTH (f))
2669 width = FRAME_NEW_WIDTH (f);
2670 else
2671 width = FRAME_WIDTH (f);
2672
2673 if (FRAME_NEW_HEIGHT (f))
2674 height = FRAME_NEW_HEIGHT (f);
2675 else
2676 height = FRAME_HEIGHT (f);
2677
2678 /* Process foreground_color and background_color before anything else.
2679 They are independent of other properties, but other properties (e.g.,
2680 cursor_color) are dependent upon them. */
2681 /* Process default font as well, since fringe widths depends on it. */
2682 /* Also, process fullscreen, width and height depend upon that */
2683 for (p = 0; p < i; p++)
2684 {
2685 Lisp_Object prop, val;
2686
2687 prop = parms[p];
2688 val = values[p];
2689 if (EQ (prop, Qforeground_color)
2690 || EQ (prop, Qbackground_color)
2691 || EQ (prop, Qfont)
2692 || EQ (prop, Qfullscreen))
2693 {
2694 register Lisp_Object param_index, old_value;
2695
2696 old_value = get_frame_param (f, prop);
2697 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
2698
2699 if (NILP (Fequal (val, old_value)))
2700 {
2701 store_frame_param (f, prop, val);
2702
2703 param_index = Fget (prop, Qx_frame_parameter);
2704 if (NATNUMP (param_index)
2705 && (XFASTINT (param_index)
2706 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2707 && rif->frame_parm_handlers[XINT (param_index)])
2708 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2709 }
2710 }
2711 }
2712
2713 /* Now process them in reverse of specified order. */
2714 for (i--; i >= 0; i--)
2715 {
2716 Lisp_Object prop, val;
2717
2718 prop = parms[i];
2719 val = values[i];
2720
2721 if (EQ (prop, Qwidth) && NUMBERP (val))
2722 width = XFASTINT (val);
2723 else if (EQ (prop, Qheight) && NUMBERP (val))
2724 height = XFASTINT (val);
2725 else if (EQ (prop, Qtop))
2726 top = val;
2727 else if (EQ (prop, Qleft))
2728 left = val;
2729 else if (EQ (prop, Qicon_top))
2730 icon_top = val;
2731 else if (EQ (prop, Qicon_left))
2732 icon_left = val;
2733 else if (EQ (prop, Qforeground_color)
2734 || EQ (prop, Qbackground_color)
2735 || EQ (prop, Qfont)
2736 || EQ (prop, Qfullscreen))
2737 /* Processed above. */
2738 continue;
2739 else
2740 {
2741 register Lisp_Object param_index, old_value;
2742
2743 old_value = get_frame_param (f, prop);
2744
2745 store_frame_param (f, prop, val);
2746
2747 param_index = Fget (prop, Qx_frame_parameter);
2748 if (NATNUMP (param_index)
2749 && (XFASTINT (param_index)
2750 < sizeof (frame_parms)/sizeof (frame_parms[0]))
2751 && rif->frame_parm_handlers[XINT (param_index)])
2752 (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2753 }
2754 }
2755
2756 /* Don't die if just one of these was set. */
2757 if (EQ (left, Qunbound))
2758 {
2759 left_no_change = 1;
2760 if (FRAME_X_OUTPUT (f)->left_pos < 0)
2761 left = Fcons (Qplus, Fcons (make_number (FRAME_X_OUTPUT (f)->left_pos), Qnil));
2762 else
2763 XSETINT (left, FRAME_X_OUTPUT (f)->left_pos);
2764 }
2765 if (EQ (top, Qunbound))
2766 {
2767 top_no_change = 1;
2768 if (FRAME_X_OUTPUT (f)->top_pos < 0)
2769 top = Fcons (Qplus, Fcons (make_number (FRAME_X_OUTPUT (f)->top_pos), Qnil));
2770 else
2771 XSETINT (top, FRAME_X_OUTPUT (f)->top_pos);
2772 }
2773
2774 /* If one of the icon positions was not set, preserve or default it. */
2775 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
2776 {
2777 icon_left_no_change = 1;
2778 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
2779 if (NILP (icon_left))
2780 XSETINT (icon_left, 0);
2781 }
2782 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
2783 {
2784 icon_top_no_change = 1;
2785 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
2786 if (NILP (icon_top))
2787 XSETINT (icon_top, 0);
2788 }
2789
2790 #ifndef HAVE_CARBON
2791 /* MAC_TODO: fullscreen */
2792 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
2793 {
2794 /* If the frame is visible already and the fullscreen parameter is
2795 being set, it is too late to set WM manager hints to specify
2796 size and position.
2797 Here we first get the width, height and position that applies to
2798 fullscreen. We then move the frame to the appropriate
2799 position. Resize of the frame is taken care of in the code after
2800 this if-statement. */
2801 int new_left, new_top;
2802
2803 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
2804 x_fullscreen_move (f, new_top, new_left);
2805 }
2806 #endif
2807
2808 /* Don't set these parameters unless they've been explicitly
2809 specified. The window might be mapped or resized while we're in
2810 this function, and we don't want to override that unless the lisp
2811 code has asked for it.
2812
2813 Don't set these parameters unless they actually differ from the
2814 window's current parameters; the window may not actually exist
2815 yet. */
2816 {
2817 Lisp_Object frame;
2818
2819 check_frame_size (f, &height, &width);
2820
2821 XSETFRAME (frame, f);
2822
2823 if (width != FRAME_WIDTH (f)
2824 || height != FRAME_HEIGHT (f)
2825 || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2826 Fset_frame_size (frame, make_number (width), make_number (height));
2827
2828 if ((!NILP (left) || !NILP (top))
2829 && ! (left_no_change && top_no_change)
2830 && ! (NUMBERP (left) && XINT (left) == FRAME_X_OUTPUT (f)->left_pos
2831 && NUMBERP (top) && XINT (top) == FRAME_X_OUTPUT (f)->top_pos))
2832 {
2833 int leftpos = 0;
2834 int toppos = 0;
2835
2836 /* Record the signs. */
2837 FRAME_X_OUTPUT (f)->size_hint_flags &= ~ (XNegative | YNegative);
2838 if (EQ (left, Qminus))
2839 FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2840 else if (INTEGERP (left))
2841 {
2842 leftpos = XINT (left);
2843 if (leftpos < 0)
2844 FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2845 }
2846 else if (CONSP (left) && EQ (XCAR (left), Qminus)
2847 && CONSP (XCDR (left))
2848 && INTEGERP (XCAR (XCDR (left))))
2849 {
2850 leftpos = - XINT (XCAR (XCDR (left)));
2851 FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2852 }
2853 else if (CONSP (left) && EQ (XCAR (left), Qplus)
2854 && CONSP (XCDR (left))
2855 && INTEGERP (XCAR (XCDR (left))))
2856 {
2857 leftpos = XINT (XCAR (XCDR (left)));
2858 }
2859
2860 if (EQ (top, Qminus))
2861 FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2862 else if (INTEGERP (top))
2863 {
2864 toppos = XINT (top);
2865 if (toppos < 0)
2866 FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2867 }
2868 else if (CONSP (top) && EQ (XCAR (top), Qminus)
2869 && CONSP (XCDR (top))
2870 && INTEGERP (XCAR (XCDR (top))))
2871 {
2872 toppos = - XINT (XCAR (XCDR (top)));
2873 FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2874 }
2875 else if (CONSP (top) && EQ (XCAR (top), Qplus)
2876 && CONSP (XCDR (top))
2877 && INTEGERP (XCAR (XCDR (top))))
2878 {
2879 toppos = XINT (XCAR (XCDR (top)));
2880 }
2881
2882
2883 /* Store the numeric value of the position. */
2884 FRAME_X_OUTPUT (f)->top_pos = toppos;
2885 FRAME_X_OUTPUT (f)->left_pos = leftpos;
2886
2887 FRAME_X_OUTPUT (f)->win_gravity = NorthWestGravity;
2888
2889 /* Actually set that position, and convert to absolute. */
2890 x_set_offset (f, leftpos, toppos, -1);
2891 }
2892
2893 if ((!NILP (icon_left) || !NILP (icon_top))
2894 && ! (icon_left_no_change && icon_top_no_change))
2895 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
2896 }
2897
2898 UNGCPRO;
2899 }
2900
2901
2902 /* Insert a description of internally-recorded parameters of frame X
2903 into the parameter alist *ALISTPTR that is to be given to the user.
2904 Only parameters that are specific to the X window system
2905 and whose values are not correctly recorded in the frame's
2906 param_alist need to be considered here. */
2907
2908 void
2909 x_report_frame_params (f, alistptr)
2910 struct frame *f;
2911 Lisp_Object *alistptr;
2912 {
2913 char buf[16];
2914 Lisp_Object tem;
2915
2916 /* Represent negative positions (off the top or left screen edge)
2917 in a way that Fmodify_frame_parameters will understand correctly. */
2918 XSETINT (tem, FRAME_X_OUTPUT (f)->left_pos);
2919 if (FRAME_X_OUTPUT (f)->left_pos >= 0)
2920 store_in_alist (alistptr, Qleft, tem);
2921 else
2922 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
2923
2924 XSETINT (tem, FRAME_X_OUTPUT (f)->top_pos);
2925 if (FRAME_X_OUTPUT (f)->top_pos >= 0)
2926 store_in_alist (alistptr, Qtop, tem);
2927 else
2928 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
2929
2930 store_in_alist (alistptr, Qborder_width,
2931 make_number (FRAME_X_OUTPUT (f)->border_width));
2932 store_in_alist (alistptr, Qinternal_border_width,
2933 make_number (FRAME_X_OUTPUT (f)->internal_border_width));
2934 store_in_alist (alistptr, Qleft_fringe,
2935 make_number (FRAME_X_OUTPUT (f)->left_fringe_width));
2936 store_in_alist (alistptr, Qright_fringe,
2937 make_number (FRAME_X_OUTPUT (f)->right_fringe_width));
2938 store_in_alist (alistptr, Qscroll_bar_width,
2939 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
2940 ? make_number (0)
2941 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
2942 ? make_number (FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
2943 /* nil means "use default width"
2944 for non-toolkit scroll bar.
2945 ruler-mode.el depends on this. */
2946 : Qnil));
2947 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
2948 store_in_alist (alistptr, Qwindow_id,
2949 build_string (buf));
2950 #ifdef HAVE_X_WINDOWS
2951 #ifdef USE_X_TOOLKIT
2952 /* Tooltip frame may not have this widget. */
2953 if (FRAME_X_OUTPUT (f)->widget)
2954 #endif
2955 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
2956 store_in_alist (alistptr, Qouter_window_id,
2957 build_string (buf));
2958 #endif
2959 store_in_alist (alistptr, Qicon_name, f->icon_name);
2960 FRAME_SAMPLE_VISIBILITY (f);
2961 store_in_alist (alistptr, Qvisibility,
2962 (FRAME_VISIBLE_P (f) ? Qt
2963 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
2964 store_in_alist (alistptr, Qdisplay,
2965 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
2966
2967 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
2968 tem = Qnil;
2969 else
2970 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
2971 store_in_alist (alistptr, Qparent_id, tem);
2972 }
2973
2974
2975 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
2976 the previous value of that parameter, NEW_VALUE is the new value. */
2977
2978 void
2979 x_set_fullscreen (f, new_value, old_value)
2980 struct frame *f;
2981 Lisp_Object new_value, old_value;
2982 {
2983 #ifndef HAVE_CARBON
2984 if (NILP (new_value))
2985 FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_NONE;
2986 else if (EQ (new_value, Qfullboth))
2987 FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_BOTH;
2988 else if (EQ (new_value, Qfullwidth))
2989 FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_WIDTH;
2990 else if (EQ (new_value, Qfullheight))
2991 FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_HEIGHT;
2992 #endif
2993 }
2994
2995
2996 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
2997 the previous value of that parameter, NEW_VALUE is the new value. */
2998
2999 void
3000 x_set_line_spacing (f, new_value, old_value)
3001 struct frame *f;
3002 Lisp_Object new_value, old_value;
3003 {
3004 if (NILP (new_value))
3005 f->extra_line_spacing = 0;
3006 else if (NATNUMP (new_value))
3007 f->extra_line_spacing = XFASTINT (new_value);
3008 else
3009 Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),
3010 Fcons (new_value, Qnil)));
3011 if (FRAME_VISIBLE_P (f))
3012 redraw_frame (f);
3013 }
3014
3015
3016 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3017 the previous value of that parameter, NEW_VALUE is the new value. */
3018
3019 void
3020 x_set_screen_gamma (f, new_value, old_value)
3021 struct frame *f;
3022 Lisp_Object new_value, old_value;
3023 {
3024 if (NILP (new_value))
3025 f->gamma = 0;
3026 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3027 /* The value 0.4545 is the normal viewing gamma. */
3028 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3029 else
3030 Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),
3031 Fcons (new_value, Qnil)));
3032
3033 clear_face_cache (0);
3034 }
3035
3036
3037 void
3038 x_set_font (f, arg, oldval)
3039 struct frame *f;
3040 Lisp_Object arg, oldval;
3041 {
3042 Lisp_Object result;
3043 Lisp_Object fontset_name;
3044 Lisp_Object frame;
3045 int old_fontset = FRAME_FONTSET(f);
3046
3047 CHECK_STRING (arg);
3048
3049 fontset_name = Fquery_fontset (arg, Qnil);
3050
3051 BLOCK_INPUT;
3052 result = (STRINGP (fontset_name)
3053 ? x_new_fontset (f, SDATA (fontset_name))
3054 : x_new_font (f, SDATA (arg)));
3055 UNBLOCK_INPUT;
3056
3057 if (EQ (result, Qnil))
3058 error ("Font `%s' is not defined", SDATA (arg));
3059 else if (EQ (result, Qt))
3060 error ("The characters of the given font have varying widths");
3061 else if (STRINGP (result))
3062 {
3063 if (STRINGP (fontset_name))
3064 {
3065 /* Fontset names are built from ASCII font names, so the
3066 names may be equal despite there was a change. */
3067 if (old_fontset == FRAME_FONTSET (f))
3068 return;
3069 }
3070 else if (!NILP (Fequal (result, oldval)))
3071 return;
3072
3073 store_frame_param (f, Qfont, result);
3074 recompute_basic_faces (f);
3075 }
3076 else
3077 abort ();
3078
3079 do_pending_window_change (0);
3080
3081 /* Don't call `face-set-after-frame-default' when faces haven't been
3082 initialized yet. This is the case when called from
3083 Fx_create_frame. In that case, the X widget or window doesn't
3084 exist either, and we can end up in x_report_frame_params with a
3085 null widget which gives a segfault. */
3086 if (FRAME_FACE_CACHE (f))
3087 {
3088 XSETFRAME (frame, f);
3089 call1 (Qface_set_after_frame_default, frame);
3090 }
3091 }
3092
3093
3094 void
3095 x_set_fringe_width (f, new_value, old_value)
3096 struct frame *f;
3097 Lisp_Object new_value, old_value;
3098 {
3099 compute_fringe_widths (f, 1);
3100 }
3101
3102 void
3103 x_set_border_width (f, arg, oldval)
3104 struct frame *f;
3105 Lisp_Object arg, oldval;
3106 {
3107 CHECK_NUMBER (arg);
3108
3109 if (XINT (arg) == FRAME_X_OUTPUT (f)->border_width)
3110 return;
3111
3112 #ifndef HAVE_CARBON
3113 if (FRAME_X_WINDOW (f) != 0)
3114 error ("Cannot change the border width of a window");
3115 #endif /* MAC_TODO */
3116
3117 FRAME_X_OUTPUT (f)->border_width = XINT (arg);
3118 }
3119
3120 void
3121 x_set_internal_border_width (f, arg, oldval)
3122 struct frame *f;
3123 Lisp_Object arg, oldval;
3124 {
3125 int old = FRAME_X_OUTPUT (f)->internal_border_width;
3126
3127 CHECK_NUMBER (arg);
3128 FRAME_X_OUTPUT (f)->internal_border_width = XINT (arg);
3129 if (FRAME_X_OUTPUT (f)->internal_border_width < 0)
3130 FRAME_X_OUTPUT (f)->internal_border_width = 0;
3131
3132 #ifdef USE_X_TOOLKIT
3133 if (FRAME_X_OUTPUT (f)->edit_widget)
3134 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3135 #endif
3136
3137 if (FRAME_X_OUTPUT (f)->internal_border_width == old)
3138 return;
3139
3140 if (FRAME_X_WINDOW (f) != 0)
3141 {
3142 x_set_window_size (f, 0, f->width, f->height);
3143 SET_FRAME_GARBAGED (f);
3144 do_pending_window_change (0);
3145 }
3146 else
3147 SET_FRAME_GARBAGED (f);
3148 }
3149
3150 void
3151 x_set_visibility (f, value, oldval)
3152 struct frame *f;
3153 Lisp_Object value, oldval;
3154 {
3155 Lisp_Object frame;
3156 XSETFRAME (frame, f);
3157
3158 if (NILP (value))
3159 Fmake_frame_invisible (frame, Qt);
3160 else if (EQ (value, Qicon))
3161 Ficonify_frame (frame);
3162 else
3163 Fmake_frame_visible (frame);
3164 }
3165
3166 void
3167 x_set_autoraise (f, arg, oldval)
3168 struct frame *f;
3169 Lisp_Object arg, oldval;
3170 {
3171 f->auto_raise = !EQ (Qnil, arg);
3172 }
3173
3174 void
3175 x_set_autolower (f, arg, oldval)
3176 struct frame *f;
3177 Lisp_Object arg, oldval;
3178 {
3179 f->auto_lower = !EQ (Qnil, arg);
3180 }
3181
3182 void
3183 x_set_unsplittable (f, arg, oldval)
3184 struct frame *f;
3185 Lisp_Object arg, oldval;
3186 {
3187 f->no_split = !NILP (arg);
3188 }
3189
3190 void
3191 x_set_vertical_scroll_bars (f, arg, oldval)
3192 struct frame *f;
3193 Lisp_Object arg, oldval;
3194 {
3195 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3196 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3197 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3198 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3199 {
3200 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3201 = (NILP (arg)
3202 ? vertical_scroll_bar_none
3203 : EQ (Qleft, arg)
3204 ? vertical_scroll_bar_left
3205 : EQ (Qright, arg)
3206 ? vertical_scroll_bar_right
3207 #ifdef HAVE_NTGUI
3208 /* MS-Windows has scroll bars on the right by default. */
3209 : vertical_scroll_bar_right
3210 #else
3211 : vertical_scroll_bar_left
3212 #endif
3213 );
3214
3215 /* We set this parameter before creating the X window for the
3216 frame, so we can get the geometry right from the start.
3217 However, if the window hasn't been created yet, we shouldn't
3218 call x_set_window_size. */
3219 if (FRAME_X_WINDOW (f))
3220 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3221 do_pending_window_change (0);
3222 }
3223 }
3224
3225 void
3226 x_set_scroll_bar_width (f, arg, oldval)
3227 struct frame *f;
3228 Lisp_Object arg, oldval;
3229 {
3230 int wid = FONT_WIDTH (FRAME_FONT (f));
3231
3232 if (NILP (arg))
3233 {
3234 x_set_scroll_bar_default_width (f);
3235
3236 if (FRAME_X_WINDOW (f))
3237 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3238 do_pending_window_change (0);
3239 }
3240 else if (INTEGERP (arg) && XINT (arg) > 0
3241 && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
3242 {
3243 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3244 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3245
3246 FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);
3247 FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3248 if (FRAME_X_WINDOW (f))
3249 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3250 do_pending_window_change (0);
3251 }
3252
3253 change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0, 0);
3254 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3255 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3256 }
3257
3258
3259
3260 /* Return non-nil if frame F wants a bitmap icon. */
3261
3262 Lisp_Object
3263 x_icon_type (f)
3264 FRAME_PTR f;
3265 {
3266 Lisp_Object tem;
3267
3268 tem = assq_no_quit (Qicon_type, f->param_alist);
3269 if (CONSP (tem))
3270 return XCDR (tem);
3271 else
3272 return Qnil;
3273 }
3274
3275
3276 /* Subroutines of creating an X frame. */
3277
3278 /* Make sure that Vx_resource_name is set to a reasonable value.
3279 Fix it up, or set it to `emacs' if it is too hopeless. */
3280
3281 void
3282 validate_x_resource_name ()
3283 {
3284 int len = 0;
3285 /* Number of valid characters in the resource name. */
3286 int good_count = 0;
3287 /* Number of invalid characters in the resource name. */
3288 int bad_count = 0;
3289 Lisp_Object new;
3290 int i;
3291
3292 if (!STRINGP (Vx_resource_class))
3293 Vx_resource_class = build_string (EMACS_CLASS);
3294
3295 if (STRINGP (Vx_resource_name))
3296 {
3297 unsigned char *p = SDATA (Vx_resource_name);
3298 int i;
3299
3300 len = SBYTES (Vx_resource_name);
3301
3302 /* Only letters, digits, - and _ are valid in resource names.
3303 Count the valid characters and count the invalid ones. */
3304 for (i = 0; i < len; i++)
3305 {
3306 int c = p[i];
3307 if (! ((c >= 'a' && c <= 'z')
3308 || (c >= 'A' && c <= 'Z')
3309 || (c >= '0' && c <= '9')
3310 || c == '-' || c == '_'))
3311 bad_count++;
3312 else
3313 good_count++;
3314 }
3315 }
3316 else
3317 /* Not a string => completely invalid. */
3318 bad_count = 5, good_count = 0;
3319
3320 /* If name is valid already, return. */
3321 if (bad_count == 0)
3322 return;
3323
3324 /* If name is entirely invalid, or nearly so, use `emacs'. */
3325 if (good_count == 0
3326 || (good_count == 1 && bad_count > 0))
3327 {
3328 Vx_resource_name = build_string ("emacs");
3329 return;
3330 }
3331
3332 /* Name is partly valid. Copy it and replace the invalid characters
3333 with underscores. */
3334
3335 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3336
3337 for (i = 0; i < len; i++)
3338 {
3339 int c = SREF (new, i);
3340 if (! ((c >= 'a' && c <= 'z')
3341 || (c >= 'A' && c <= 'Z')
3342 || (c >= '0' && c <= '9')
3343 || c == '-' || c == '_'))
3344 SSET (new, i, '_');
3345 }
3346 }
3347
3348
3349 extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3350 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3351
3352
3353 /* Get specified attribute from resource database RDB.
3354 See Fx_get_resource below for other parameters. */
3355
3356 static Lisp_Object
3357 xrdb_get_resource (rdb, attribute, class, component, subclass)
3358 XrmDatabase rdb;
3359 Lisp_Object attribute, class, component, subclass;
3360 {
3361 register char *value;
3362 char *name_key;
3363 char *class_key;
3364
3365 CHECK_STRING (attribute);
3366 CHECK_STRING (class);
3367
3368 if (!NILP (component))
3369 CHECK_STRING (component);
3370 if (!NILP (subclass))
3371 CHECK_STRING (subclass);
3372 if (NILP (component) != NILP (subclass))
3373 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3374
3375 validate_x_resource_name ();
3376
3377 /* Allocate space for the components, the dots which separate them,
3378 and the final '\0'. Make them big enough for the worst case. */
3379 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3380 + (STRINGP (component)
3381 ? SBYTES (component) : 0)
3382 + SBYTES (attribute)
3383 + 3);
3384
3385 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3386 + SBYTES (class)
3387 + (STRINGP (subclass)
3388 ? SBYTES (subclass) : 0)
3389 + 3);
3390
3391 /* Start with emacs.FRAMENAME for the name (the specific one)
3392 and with `Emacs' for the class key (the general one). */
3393 strcpy (name_key, SDATA (Vx_resource_name));
3394 strcpy (class_key, SDATA (Vx_resource_class));
3395
3396 strcat (class_key, ".");
3397 strcat (class_key, SDATA (class));
3398
3399 if (!NILP (component))
3400 {
3401 strcat (class_key, ".");
3402 strcat (class_key, SDATA (subclass));
3403
3404 strcat (name_key, ".");
3405 strcat (name_key, SDATA (component));
3406 }
3407
3408 strcat (name_key, ".");
3409 strcat (name_key, SDATA (attribute));
3410
3411 value = x_get_string_resource (rdb, name_key, class_key);
3412
3413 if (value != (char *) 0)
3414 return build_string (value);
3415 else
3416 return Qnil;
3417 }
3418
3419
3420 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3421 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3422 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3423 class, where INSTANCE is the name under which Emacs was invoked, or
3424 the name specified by the `-name' or `-rn' command-line arguments.
3425
3426 The optional arguments COMPONENT and SUBCLASS add to the key and the
3427 class, respectively. You must specify both of them or neither.
3428 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3429 and the class is `Emacs.CLASS.SUBCLASS'. */)
3430 (attribute, class, component, subclass)
3431 Lisp_Object attribute, class, component, subclass;
3432 {
3433 #ifdef HAVE_X_WINDOWS
3434 check_x ();
3435 #endif
3436
3437 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3438 attribute, class, component, subclass);
3439 }
3440
3441 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3442
3443 Lisp_Object
3444 display_x_get_resource (dpyinfo, attribute, class, component, subclass)
3445 struct x_display_info *dpyinfo;
3446 Lisp_Object attribute, class, component, subclass;
3447 {
3448 return xrdb_get_resource (dpyinfo->xrdb,
3449 attribute, class, component, subclass);
3450 }
3451
3452 /* Used when C code wants a resource value. */
3453
3454 char *
3455 x_get_resource_string (attribute, class)
3456 char *attribute, *class;
3457 {
3458 char *name_key;
3459 char *class_key;
3460 struct frame *sf = SELECTED_FRAME ();
3461
3462 /* Allocate space for the components, the dots which separate them,
3463 and the final '\0'. */
3464 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3465 + strlen (attribute) + 2);
3466 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3467 + strlen (class) + 2);
3468
3469 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3470 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3471
3472 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3473 name_key, class_key);
3474 }
3475
3476
3477 /* Return the value of parameter PARAM.
3478
3479 First search ALIST, then Vdefault_frame_alist, then the X defaults
3480 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3481
3482 Convert the resource to the type specified by desired_type.
3483
3484 If no default is specified, return Qunbound. If you call
3485 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3486 and don't let it get stored in any Lisp-visible variables! */
3487
3488 Lisp_Object
3489 x_get_arg (dpyinfo, alist, param, attribute, class, type)
3490 Display_Info *dpyinfo;
3491 Lisp_Object alist, param;
3492 char *attribute;
3493 char *class;
3494 enum resource_types type;
3495 {
3496 register Lisp_Object tem;
3497
3498 tem = Fassq (param, alist);
3499 if (EQ (tem, Qnil))
3500 tem = Fassq (param, Vdefault_frame_alist);
3501 if (EQ (tem, Qnil))
3502 {
3503 if (attribute)
3504 {
3505 tem = display_x_get_resource (dpyinfo,
3506 build_string (attribute),
3507 build_string (class),
3508 Qnil, Qnil);
3509
3510 if (NILP (tem))
3511 return Qunbound;
3512
3513 switch (type)
3514 {
3515 case RES_TYPE_NUMBER:
3516 return make_number (atoi (SDATA (tem)));
3517
3518 case RES_TYPE_FLOAT:
3519 return make_float (atof (SDATA (tem)));
3520
3521 case RES_TYPE_BOOLEAN:
3522 tem = Fdowncase (tem);
3523 if (!strcmp (SDATA (tem), "on")
3524 || !strcmp (SDATA (tem), "true"))
3525 return Qt;
3526 else
3527 return Qnil;
3528
3529 case RES_TYPE_STRING:
3530 return tem;
3531
3532 case RES_TYPE_SYMBOL:
3533 /* As a special case, we map the values `true' and `on'
3534 to Qt, and `false' and `off' to Qnil. */
3535 {
3536 Lisp_Object lower;
3537 lower = Fdowncase (tem);
3538 if (!strcmp (SDATA (lower), "on")
3539 || !strcmp (SDATA (lower), "true"))
3540 return Qt;
3541 else if (!strcmp (SDATA (lower), "off")
3542 || !strcmp (SDATA (lower), "false"))
3543 return Qnil;
3544 else
3545 return Fintern (tem, Qnil);
3546 }
3547
3548 default:
3549 abort ();
3550 }
3551 }
3552 else
3553 return Qunbound;
3554 }
3555 return Fcdr (tem);
3556 }
3557
3558 Lisp_Object
3559 x_frame_get_arg (f, alist, param, attribute, class, type)
3560 struct frame *f;
3561 Lisp_Object alist, param;
3562 char *attribute;
3563 char *class;
3564 enum resource_types type;
3565 {
3566 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3567 alist, param, attribute, class, type);
3568 }
3569
3570 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
3571
3572 Lisp_Object
3573 x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
3574 struct frame *f;
3575 Lisp_Object alist, param;
3576 char *attribute;
3577 char *class;
3578 enum resource_types type;
3579 {
3580 Lisp_Object value;
3581
3582 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3583 attribute, class, type);
3584 if (! NILP (value))
3585 store_frame_param (f, param, value);
3586
3587 return value;
3588 }
3589
3590
3591 /* Record in frame F the specified or default value according to ALIST
3592 of the parameter named PROP (a Lisp symbol).
3593 If no value is specified for PROP, look for an X default for XPROP
3594 on the frame named NAME.
3595 If that is not found either, use the value DEFLT. */
3596
3597 Lisp_Object
3598 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
3599 struct frame *f;
3600 Lisp_Object alist;
3601 Lisp_Object prop;
3602 Lisp_Object deflt;
3603 char *xprop;
3604 char *xclass;
3605 enum resource_types type;
3606 {
3607 Lisp_Object tem;
3608
3609 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3610 if (EQ (tem, Qunbound))
3611 tem = deflt;
3612 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3613 return tem;
3614 }
3615
3616
3617
3618
3619 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3620 doc: /* Parse an X-style geometry string STRING.
3621 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3622 The properties returned may include `top', `left', `height', and `width'.
3623 The value of `left' or `top' may be an integer,
3624 or a list (+ N) meaning N pixels relative to top/left corner,
3625 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
3626 (string)
3627 Lisp_Object string;
3628 {
3629 int geometry, x, y;
3630 unsigned int width, height;
3631 Lisp_Object result;
3632
3633 CHECK_STRING (string);
3634
3635 geometry = XParseGeometry ((char *) SDATA (string),
3636 &x, &y, &width, &height);
3637
3638 #if 0
3639 if (!!(geometry & XValue) != !!(geometry & YValue))
3640 error ("Must specify both x and y position, or neither");
3641 #endif
3642
3643 result = Qnil;
3644 if (geometry & XValue)
3645 {
3646 Lisp_Object element;
3647
3648 if (x >= 0 && (geometry & XNegative))
3649 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3650 else if (x < 0 && ! (geometry & XNegative))
3651 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3652 else
3653 element = Fcons (Qleft, make_number (x));
3654 result = Fcons (element, result);
3655 }
3656
3657 if (geometry & YValue)
3658 {
3659 Lisp_Object element;
3660
3661 if (y >= 0 && (geometry & YNegative))
3662 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3663 else if (y < 0 && ! (geometry & YNegative))
3664 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3665 else
3666 element = Fcons (Qtop, make_number (y));
3667 result = Fcons (element, result);
3668 }
3669
3670 if (geometry & WidthValue)
3671 result = Fcons (Fcons (Qwidth, make_number (width)), result);
3672 if (geometry & HeightValue)
3673 result = Fcons (Fcons (Qheight, make_number (height)), result);
3674
3675 return result;
3676 }
3677
3678 /* Calculate the desired size and position of frame F.
3679 Return the flags saying which aspects were specified.
3680
3681 Also set the win_gravity and size_hint_flags of F.
3682
3683 Adjust height for toolbar if TOOLBAR_P is 1.
3684
3685 This function does not make the coordinates positive. */
3686
3687 #define DEFAULT_ROWS 40
3688 #define DEFAULT_COLS 80
3689
3690 int
3691 x_figure_window_size (f, parms, toolbar_p)
3692 struct frame *f;
3693 Lisp_Object parms;
3694 int toolbar_p;
3695 {
3696 register Lisp_Object tem0, tem1, tem2;
3697 long window_prompting = 0;
3698 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3699
3700 /* Default values if we fall through.
3701 Actually, if that happens we should get
3702 window manager prompting. */
3703 SET_FRAME_WIDTH (f, DEFAULT_COLS);
3704 f->height = DEFAULT_ROWS;
3705 /* Window managers expect that if program-specified
3706 positions are not (0,0), they're intentional, not defaults. */
3707 FRAME_X_OUTPUT (f)->top_pos = 0;
3708 FRAME_X_OUTPUT (f)->left_pos = 0;
3709
3710 /* Ensure that old new_width and new_height will not override the
3711 values set here. */
3712 /* ++KFS: This was specific to W32, but seems ok for all platforms */
3713 FRAME_NEW_WIDTH (f) = 0;
3714 FRAME_NEW_HEIGHT (f) = 0;
3715
3716 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
3717 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
3718 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
3719 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3720 {
3721 if (!EQ (tem0, Qunbound))
3722 {
3723 CHECK_NUMBER (tem0);
3724 f->height = XINT (tem0);
3725 }
3726 if (!EQ (tem1, Qunbound))
3727 {
3728 CHECK_NUMBER (tem1);
3729 SET_FRAME_WIDTH (f, XINT (tem1));
3730 }
3731 if (!NILP (tem2) && !EQ (tem2, Qunbound))
3732 window_prompting |= USSize;
3733 else
3734 window_prompting |= PSize;
3735 }
3736
3737 FRAME_X_OUTPUT (f)->vertical_scroll_bar_extra
3738 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3739 ? 0
3740 #ifndef HAVE_X_WINDOWS
3741 /* +KFS: This was specific for W32 and MAC.. why? */
3742 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
3743 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
3744 #endif
3745 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (FRAME_X_OUTPUT (f)->font)));
3746
3747 /* This used to be done _before_ calling x_figure_window_size, but
3748 since the height is reset here, this was really a no-op. I
3749 assume that moving it here does what Gerd intended (although he
3750 no longer can remember what that was... ++KFS, 2003-03-25. */
3751
3752 /* Add the tool-bar height to the initial frame height so that the
3753 user gets a text display area of the size he specified with -g or
3754 via .Xdefaults. Later changes of the tool-bar height don't
3755 change the frame size. This is done so that users can create
3756 tall Emacs frames without having to guess how tall the tool-bar
3757 will get. */
3758 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
3759 {
3760 int margin, relief, bar_height;
3761
3762 relief = (tool_bar_button_relief >= 0
3763 ? tool_bar_button_relief
3764 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
3765
3766 if (INTEGERP (Vtool_bar_button_margin)
3767 && XINT (Vtool_bar_button_margin) > 0)
3768 margin = XFASTINT (Vtool_bar_button_margin);
3769 else if (CONSP (Vtool_bar_button_margin)
3770 && INTEGERP (XCDR (Vtool_bar_button_margin))
3771 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
3772 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
3773 else
3774 margin = 0;
3775
3776 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
3777 f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
3778 }
3779
3780 compute_fringe_widths (f, 0);
3781
3782 FRAME_X_OUTPUT (f)->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
3783 FRAME_X_OUTPUT (f)->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
3784
3785 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
3786 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
3787 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
3788 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3789 {
3790 if (EQ (tem0, Qminus))
3791 {
3792 FRAME_X_OUTPUT (f)->top_pos = 0;
3793 window_prompting |= YNegative;
3794 }
3795 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
3796 && CONSP (XCDR (tem0))
3797 && INTEGERP (XCAR (XCDR (tem0))))
3798 {
3799 FRAME_X_OUTPUT (f)->top_pos = - XINT (XCAR (XCDR (tem0)));
3800 window_prompting |= YNegative;
3801 }
3802 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
3803 && CONSP (XCDR (tem0))
3804 && INTEGERP (XCAR (XCDR (tem0))))
3805 {
3806 FRAME_X_OUTPUT (f)->top_pos = XINT (XCAR (XCDR (tem0)));
3807 }
3808 else if (EQ (tem0, Qunbound))
3809 FRAME_X_OUTPUT (f)->top_pos = 0;
3810 else
3811 {
3812 CHECK_NUMBER (tem0);
3813 FRAME_X_OUTPUT (f)->top_pos = XINT (tem0);
3814 if (FRAME_X_OUTPUT (f)->top_pos < 0)
3815 window_prompting |= YNegative;
3816 }
3817
3818 if (EQ (tem1, Qminus))
3819 {
3820 FRAME_X_OUTPUT (f)->left_pos = 0;
3821 window_prompting |= XNegative;
3822 }
3823 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
3824 && CONSP (XCDR (tem1))
3825 && INTEGERP (XCAR (XCDR (tem1))))
3826 {
3827 FRAME_X_OUTPUT (f)->left_pos = - XINT (XCAR (XCDR (tem1)));
3828 window_prompting |= XNegative;
3829 }
3830 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
3831 && CONSP (XCDR (tem1))
3832 && INTEGERP (XCAR (XCDR (tem1))))
3833 {
3834 FRAME_X_OUTPUT (f)->left_pos = XINT (XCAR (XCDR (tem1)));
3835 }
3836 else if (EQ (tem1, Qunbound))
3837 FRAME_X_OUTPUT (f)->left_pos = 0;
3838 else
3839 {
3840 CHECK_NUMBER (tem1);
3841 FRAME_X_OUTPUT (f)->left_pos = XINT (tem1);
3842 if (FRAME_X_OUTPUT (f)->left_pos < 0)
3843 window_prompting |= XNegative;
3844 }
3845
3846 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
3847 window_prompting |= USPosition;
3848 else
3849 window_prompting |= PPosition;
3850 }
3851
3852 if (FRAME_X_OUTPUT (f)->want_fullscreen != FULLSCREEN_NONE)
3853 {
3854 int left, top;
3855 int width, height;
3856
3857 /* It takes both for some WM:s to place it where we want */
3858 window_prompting = USPosition | PPosition;
3859 x_fullscreen_adjust (f, &width, &height, &top, &left);
3860 f->width = width;
3861 f->height = height;
3862 FRAME_X_OUTPUT (f)->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
3863 FRAME_X_OUTPUT (f)->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
3864 FRAME_X_OUTPUT (f)->left_pos = left;
3865 FRAME_X_OUTPUT (f)->top_pos = top;
3866 }
3867
3868 if (window_prompting & XNegative)
3869 {
3870 if (window_prompting & YNegative)
3871 FRAME_X_OUTPUT (f)->win_gravity = SouthEastGravity;
3872 else
3873 FRAME_X_OUTPUT (f)->win_gravity = NorthEastGravity;
3874 }
3875 else
3876 {
3877 if (window_prompting & YNegative)
3878 FRAME_X_OUTPUT (f)->win_gravity = SouthWestGravity;
3879 else
3880 FRAME_X_OUTPUT (f)->win_gravity = NorthWestGravity;
3881 }
3882
3883 FRAME_X_OUTPUT (f)->size_hint_flags = window_prompting;
3884
3885 return window_prompting;
3886 }
3887
3888
3889
3890 #endif /* HAVE_WINDOW_SYSTEM */
3891
3892
3893
3894 /***********************************************************************
3895 Initialization
3896 ***********************************************************************/
3897
2440 void 3898 void
2441 syms_of_frame () 3899 syms_of_frame ()
2442 { 3900 {
2443 Qframep = intern ("framep"); 3901 Qframep = intern ("framep");
2444 staticpro (&Qframep); 3902 staticpro (&Qframep);
2450 staticpro (&Qicon); 3908 staticpro (&Qicon);
2451 Qminibuffer = intern ("minibuffer"); 3909 Qminibuffer = intern ("minibuffer");
2452 staticpro (&Qminibuffer); 3910 staticpro (&Qminibuffer);
2453 Qmodeline = intern ("modeline"); 3911 Qmodeline = intern ("modeline");
2454 staticpro (&Qmodeline); 3912 staticpro (&Qmodeline);
2455 Qname = intern ("name");
2456 staticpro (&Qname);
2457 Qonly = intern ("only"); 3913 Qonly = intern ("only");
2458 staticpro (&Qonly); 3914 staticpro (&Qonly);
2459 Qunsplittable = intern ("unsplittable");
2460 staticpro (&Qunsplittable);
2461 Qmenu_bar_lines = intern ("menu-bar-lines");
2462 staticpro (&Qmenu_bar_lines);
2463 Qtool_bar_lines = intern ("tool-bar-lines");
2464 staticpro (&Qtool_bar_lines);
2465 Qwidth = intern ("width"); 3915 Qwidth = intern ("width");
2466 staticpro (&Qwidth); 3916 staticpro (&Qwidth);
3917 Qgeometry = intern ("geometry");
3918 staticpro (&Qgeometry);
3919 Qicon_left = intern ("icon-left");
3920 staticpro (&Qicon_left);
3921 Qicon_top = intern ("icon-top");
3922 staticpro (&Qicon_top);
3923 Qleft = intern ("left");
3924 staticpro (&Qleft);
3925 Qright = intern ("right");
3926 staticpro (&Qright);
3927 Quser_position = intern ("user-position");
3928 staticpro (&Quser_position);
3929 Quser_size = intern ("user-size");
3930 staticpro (&Quser_size);
3931 Qwindow_id = intern ("window-id");
3932 staticpro (&Qwindow_id);
3933 #ifdef HAVE_X_WINDOWS
3934 Qouter_window_id = intern ("outer-window-id");
3935 staticpro (&Qouter_window_id);
3936 #endif
3937 Qparent_id = intern ("parent-id");
3938 staticpro (&Qparent_id);
2467 Qx = intern ("x"); 3939 Qx = intern ("x");
2468 staticpro (&Qx); 3940 staticpro (&Qx);
2469 Qw32 = intern ("w32"); 3941 Qw32 = intern ("w32");
2470 staticpro (&Qw32); 3942 staticpro (&Qw32);
2471 Qpc = intern ("pc"); 3943 Qpc = intern ("pc");
2476 staticpro (&Qvisible); 3948 staticpro (&Qvisible);
2477 Qbuffer_predicate = intern ("buffer-predicate"); 3949 Qbuffer_predicate = intern ("buffer-predicate");
2478 staticpro (&Qbuffer_predicate); 3950 staticpro (&Qbuffer_predicate);
2479 Qbuffer_list = intern ("buffer-list"); 3951 Qbuffer_list = intern ("buffer-list");
2480 staticpro (&Qbuffer_list); 3952 staticpro (&Qbuffer_list);
2481 Qtitle = intern ("title");
2482 staticpro (&Qtitle);
2483 Qdisplay_type = intern ("display-type"); 3953 Qdisplay_type = intern ("display-type");
2484 staticpro (&Qdisplay_type); 3954 staticpro (&Qdisplay_type);
2485 Qbackground_mode = intern ("background-mode"); 3955 Qbackground_mode = intern ("background-mode");
2486 staticpro (&Qbackground_mode); 3956 staticpro (&Qbackground_mode);
2487 Qleft_fringe = intern ("left-fringe");
2488 staticpro (&Qleft_fringe);
2489 Qright_fringe = intern ("right-fringe");
2490 staticpro (&Qright_fringe);
2491 Qtty_color_mode = intern ("tty-color-mode"); 3957 Qtty_color_mode = intern ("tty-color-mode");
2492 staticpro (&Qtty_color_mode); 3958 staticpro (&Qtty_color_mode);
3959
3960 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
3961 staticpro (&Qface_set_after_frame_default);
3962
3963 Qfullwidth = intern ("fullwidth");
3964 staticpro (&Qfullwidth);
3965 Qfullheight = intern ("fullheight");
3966 staticpro (&Qfullheight);
3967 Qfullboth = intern ("fullboth");
3968 staticpro (&Qfullboth);
3969 Qx_resource_name = intern ("x-resource-name");
3970 staticpro (&Qx_resource_name);
3971
3972 Qx_frame_parameter = intern ("x-frame-parameter");
3973 staticpro (&Qx_frame_parameter);
3974
3975 {
3976 int i;
3977
3978 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
3979 {
3980 Lisp_Object v = intern (frame_parms[i].name);
3981 if (frame_parms[i].variable)
3982 {
3983 *frame_parms[i].variable = v;
3984 staticpro (frame_parms[i].variable);
3985 }
3986 Fput (v, Qx_frame_parameter, make_number (i));
3987 }
3988 }
3989
3990 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
3991 doc: /* The name Emacs uses to look up X resources.
3992 `x-get-resource' uses this as the first component of the instance name
3993 when requesting resource values.
3994 Emacs initially sets `x-resource-name' to the name under which Emacs
3995 was invoked, or to the value specified with the `-name' or `-rn'
3996 switches, if present.
3997
3998 It may be useful to bind this variable locally around a call
3999 to `x-get-resource'. See also the variable `x-resource-class'. */);
4000 Vx_resource_name = Qnil;
4001
4002 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4003 doc: /* The class Emacs uses to look up X resources.
4004 `x-get-resource' uses this as the first component of the instance class
4005 when requesting resource values.
4006
4007 Emacs initially sets `x-resource-class' to "Emacs".
4008
4009 Setting this variable permanently is not a reasonable thing to do,
4010 but binding this variable locally around a call to `x-get-resource'
4011 is a reasonable practice. See also the variable `x-resource-name'. */);
4012 Vx_resource_class = build_string (EMACS_CLASS);
2493 4013
2494 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist, 4014 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
2495 doc: /* Alist of default values for frame creation. 4015 doc: /* Alist of default values for frame creation.
2496 These may be set in your init file, like this: 4016 These may be set in your init file, like this:
2497 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)) 4017 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))
2598 defsubr (&Sframe_pixel_width); 4118 defsubr (&Sframe_pixel_width);
2599 defsubr (&Sset_frame_height); 4119 defsubr (&Sset_frame_height);
2600 defsubr (&Sset_frame_width); 4120 defsubr (&Sset_frame_width);
2601 defsubr (&Sset_frame_size); 4121 defsubr (&Sset_frame_size);
2602 defsubr (&Sset_frame_position); 4122 defsubr (&Sset_frame_position);
2603 } 4123
4124 #ifdef HAVE_WINDOW_SYSTEM
4125 defsubr (&Sx_get_resource);
4126 defsubr (&Sx_parse_geometry);
4127 #endif
4128
4129 }