X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fdevice-x.c;h=9ea7f0bf207d14bbb668c4fa5377832935c865dd;hp=b0cad3653e321be4a2fc9ceb2fd253eec1a6df98;hb=113b194be934327de99a168d809271db252c07c4;hpb=669565bfdc5d704dfb1d5ac1a0ec01fb3615a1ae diff --git a/src/device-x.c b/src/device-x.c index b0cad36..9ea7f0b 100644 --- a/src/device-x.c +++ b/src/device-x.c @@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA. */ #include "objects-x.h" #include "buffer.h" +#include "elhash.h" #include "events.h" #include "faces.h" #include "frame.h" @@ -316,6 +317,136 @@ Dynarr_add_validified_lisp_string (char_dynarr *cda, Lisp_Object str) validify_resource_component (Dynarr_atp (cda, Dynarr_length (cda) - len), len); } +#if 0 +/* compare visual info for qsorting */ +static int +x_comp_visual_info (const void *elem1, const void *elem2) +{ + XVisualInfo *left, *right; + + left = (XVisualInfo *)elem1; + right = (XVisualInfo *)elem2; + + if ( left == NULL ) + return -1; + if ( right == NULL ) + return 1; + + if ( left->depth > right->depth ) { + return 1; + } + else if ( left->depth == right->depth ) { + if ( left->colormap_size > right->colormap_size ) + return 1; + if ( left->class > right->class ) + return 1; + else if ( left->class < right->class ) + return -1; + else + return 0; + } + else { + return -1; + } + +} +#endif /* if 0 */ + +#define XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN +static Visual * +x_try_best_visual_class (Screen *screen, int scrnum, int visual_class) +{ + Display *dpy = DisplayOfScreen (screen); + XVisualInfo vi_in; + XVisualInfo *vi_out = NULL; + int out_count; + + vi_in.class = visual_class; + vi_in.screen = scrnum; + vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask), + &vi_in, &out_count); + if ( vi_out ) + { + int i, best; + Visual *visual; + for (i = 0, best = 0; i < out_count; i++) + /* It's better if it's deeper, or if it's the same depth with + more cells (does that ever happen? Well, it could...) + NOTE: don't allow pseudo color to get larger than 8! */ + if (((vi_out [i].depth > vi_out [best].depth) || + ((vi_out [i].depth == vi_out [best].depth) && + (vi_out [i].colormap_size > vi_out [best].colormap_size))) +#ifdef XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN + /* For now, the image library doesn't like PseudoColor visuals + of depths other than 1 or 8. Depths greater than 8 only occur + on machines which have TrueColor anyway, so probably we'll end + up using that (it is the one that `Best' would pick) but if a + PseudoColor visual is explicitly specified, pick the 8 bit one. + */ + && (visual_class != PseudoColor || + vi_out [i].depth == 1 || + vi_out [i].depth == 8) +#endif + + /* SGI has 30-bit deep visuals. Ignore them. + (We only have 24-bit data anyway.) + */ + && (vi_out [i].depth <= 24) + ) + best = i; + visual = vi_out[best].visual; + XFree ((char *) vi_out); + return visual; + } + else + return 0; +} + +static int +x_get_visual_depth (Display *dpy, Visual *visual) +{ + XVisualInfo vi_in; + XVisualInfo *vi_out; + int out_count, d; + + vi_in.visualid = XVisualIDFromVisual (visual); + vi_out = XGetVisualInfo (dpy, /*VisualScreenMask|*/VisualIDMask, + &vi_in, &out_count); + if (! vi_out) abort (); + d = vi_out [0].depth; + XFree ((char *) vi_out); + return d; +} + +static Visual * +x_try_best_visual (Display *dpy, int scrnum) +{ + Visual *visual = NULL; + Screen *screen = ScreenOfDisplay (dpy, scrnum); + if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor)) + && x_get_visual_depth (dpy, visual) >= 16 ) + return visual; + if ((visual = x_try_best_visual_class (screen, scrnum, PseudoColor))) + return visual; + if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor))) + return visual; +#ifdef DIRECTCOLOR_WORKS + if ((visual = x_try_best_visual_class (screen, scrnum, DirectColor))) + return visual; +#endif + + visual = DefaultVisualOfScreen (screen); + if ( x_get_visual_depth (dpy, visual) >= 8 ) + return visual; + + if ((visual = x_try_best_visual_class (screen, scrnum, StaticGray))) + return visual; + if ((visual = x_try_best_visual_class (screen, scrnum, GrayScale))) + return visual; + return DefaultVisualOfScreen (screen); +} + + static void x_init_device (struct device *d, Lisp_Object props) { @@ -328,12 +459,12 @@ x_init_device (struct device *d, Lisp_Object props) CONST char *app_class; CONST char *app_name; CONST char *disp_name; - Arg xargs[6]; - Cardinal numargs; Visual *visual = NULL; int depth = 8; /* shut up the compiler */ Colormap cmap; int screen; + /* */ + int best_visual_found = 0; XSETDEVICE (device, d); display = DEVICE_CONNECTION (d); @@ -348,7 +479,7 @@ x_init_device (struct device *d, Lisp_Object props) * Break apart the old XtOpenDisplay call into XOpenDisplay and * XtDisplayInitialize so we can figure out whether there * are any XEmacs resources in the resource database before - * we intitialize Xt. This is so we can automagically support + * we initialize Xt. This is so we can automagically support * both `Emacs' and `XEmacs' application classes. */ slow_down_interrupts (); @@ -387,7 +518,7 @@ x_init_device (struct device *d, Lisp_Object props) XtNumber (emacs_options), &argc, argv); speed_up_interrupts (); - screen = DefaultScreen(dpy); + screen = DefaultScreen (dpy); if (NILP (Vdefault_x_device)) Vdefault_x_device = device; @@ -400,7 +531,7 @@ x_init_device (struct device *d, Lisp_Object props) does not override resources defined elsewhere */ CONST char *data_dir; char *path; - XrmDatabase db = XtDatabase (dpy); /* ### XtScreenDatabase(dpy) ? */ + XrmDatabase db = XtDatabase (dpy); /* #### XtScreenDatabase(dpy) ? */ CONST char *locale = XrmLocaleOfDatabase (db); if (STRINGP (Vx_app_defaults_directory) && @@ -434,9 +565,8 @@ x_init_device (struct device *d, Lisp_Object props) XtGetApplicationNameAndClass (dpy, (char **) &app_name, (char **) &app_class); /* search for a matching visual if requested by the user, or setup the display default */ - numargs = 0; { - char *buf1 = (char *)alloca (strlen (app_name) + 17); + char *buf1 = (char *)alloca (strlen (app_name) + 17); char *buf2 = (char *)alloca (strlen (app_class) + 17); char *type; XrmValue value; @@ -445,85 +575,110 @@ x_init_device (struct device *d, Lisp_Object props) sprintf (buf2, "%s.EmacsVisual", app_class); if (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True) { - int cnt = 0, vis_class= PseudoColor; + int cnt = 0, vis_class = PseudoColor; XVisualInfo vinfo; char *res, *str = (char*)value.addr; - if (strncmp(str, "StaticGray", 10) == 0) cnt = 10, vis_class = StaticGray; - else if (strncmp(str, "StaticColor", 11) == 0) cnt = 11, vis_class = StaticColor; - else if (strncmp(str, "TrueColor", 9) == 0) cnt = 9, vis_class = TrueColor; - else if (strncmp(str, "GrayScale", 9) == 0) cnt = 9, vis_class = GrayScale; - else if (strncmp(str, "PseudoColor", 11) == 0) cnt = 11, vis_class = PseudoColor; - else if (strncmp(str, "DirectColor", 11) == 0) cnt = 11, vis_class = DirectColor; +#define CHECK_VIS_CLASS(class) \ + else if (strncmp (str, #class, sizeof (#class) - 1) == 0) \ + cnt = sizeof (#class) - 1, vis_class = class + + if (1) + ; + CHECK_VIS_CLASS (StaticGray); + CHECK_VIS_CLASS (StaticColor); + CHECK_VIS_CLASS (TrueColor); + CHECK_VIS_CLASS (GrayScale); + CHECK_VIS_CLASS (PseudoColor); + CHECK_VIS_CLASS (DirectColor); + if (cnt) { res = str + cnt; - depth = atoi(res); + depth = atoi (res); if (depth == 0) { - stderr_out("Invalid Depth specification in %s... ignoring...\n",(char*)str); + stderr_out ("Invalid Depth specification in %s... ignoring...\n", str); } else { - if (XMatchVisualInfo(dpy, screen, depth, vis_class, &vinfo)) + if (XMatchVisualInfo (dpy, screen, depth, vis_class, &vinfo)) { visual = vinfo.visual; } else { - stderr_out("Can't match the requested visual %s... using defaults\n",str); + stderr_out ("Can't match the requested visual %s... using defaults\n", str); } } } else { - stderr_out("Invalid Visual specification in %s... ignoring.\n",(char*)str); + stderr_out( "Invalid Visual specification in %s... ignoring.\n", str); } } if (visual == NULL) { - visual = DefaultVisual(dpy, screen); - depth = DefaultDepth(dpy, screen); + /* + visual = DefaultVisual(dpy, screen); + depth = DefaultDepth(dpy, screen); + */ + visual = x_try_best_visual (dpy, screen); + depth = x_get_visual_depth (dpy, visual); + best_visual_found = (visual != DefaultVisual (dpy, screen)); } /* If we've got the same visual as the default and it's PseudoColor, check to see if the user specified that we need a private colormap */ - if (visual == DefaultVisual(dpy, screen)) + if (visual == DefaultVisual (dpy, screen)) { sprintf (buf1, "%s.privateColormap", app_name); sprintf (buf2, "%s.PrivateColormap", app_class); if ((visual->class == PseudoColor) && (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True)) { - cmap = XCopyColormapAndFree(dpy, DefaultColormap(dpy, screen)); + cmap = XCopyColormapAndFree (dpy, DefaultColormap (dpy, screen)); } else { - cmap = DefaultColormap(dpy, screen); + cmap = DefaultColormap (dpy, screen); } } else { - /* We have to create a matching colormap anyway... - ### think about using standard colormaps (need the Xmu libs?) */ - cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone); - XInstallColormap(dpy, cmap); + if ( best_visual_found ) + { + cmap = XCreateColormap (dpy, RootWindow (dpy, screen), visual, AllocNone); + } + else + { + /* We have to create a matching colormap anyway... + ### think about using standard colormaps (need the Xmu libs?) */ + cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone); + XInstallColormap(dpy, cmap); + } } } - XtSetArg(xargs[numargs],XtNvisual, visual); numargs++; - XtSetArg(xargs[numargs],XtNdepth, depth); numargs++; - XtSetArg(xargs[numargs],XtNcolormap, cmap); numargs++; - DEVICE_X_VISUAL (d) = visual; - DEVICE_X_COLORMAP (d) = cmap; - DEVICE_X_DEPTH (d) = depth; + DEVICE_X_VISUAL (d) = visual; + DEVICE_X_COLORMAP (d) = cmap; + DEVICE_X_DEPTH (d) = depth; validify_resource_component ((char *) XSTRING_DATA (DEVICE_NAME (d)), XSTRING_LENGTH (DEVICE_NAME (d))); - app_shell = XtAppCreateShell (NULL, app_class, - applicationShellWidgetClass, - dpy, xargs, numargs); + + { + Arg al[3]; + XtSetArg (al[0], XtNvisual, visual); + XtSetArg (al[1], XtNdepth, depth); + XtSetArg (al[2], XtNcolormap, cmap); + + app_shell = XtAppCreateShell (NULL, app_class, + applicationShellWidgetClass, + dpy, al, countof (al)); + } DEVICE_XT_APP_SHELL (d) = app_shell; + #ifdef HAVE_XIM XIM_init_device(d); #endif /* HAVE_XIM */ @@ -531,20 +686,17 @@ x_init_device (struct device *d, Lisp_Object props) /* Realize the app_shell so that its window exists for GC creation purposes, and set it to the size of the root window for child placement purposes */ { - Screen *scrn = ScreenOfDisplay(dpy, screen); - int screen_width, screen_height; - screen_width = WidthOfScreen(scrn); - screen_height = HeightOfScreen(scrn); - numargs = 0; - XtSetArg (xargs[numargs], XtNmappedWhenManaged, False); numargs++; - XtSetArg (xargs[numargs], XtNx, 0); numargs++; - XtSetArg (xargs[numargs], XtNy, 0); numargs++; - XtSetArg (xargs[numargs], XtNwidth, screen_width); numargs++; - XtSetArg (xargs[numargs], XtNheight, screen_height); numargs++; - XtSetValues (app_shell, xargs, numargs); + Arg al[5]; + XtSetArg (al[0], XtNmappedWhenManaged, False); + XtSetArg (al[1], XtNx, 0); + XtSetArg (al[2], XtNy, 0); + XtSetArg (al[3], XtNwidth, WidthOfScreen (ScreenOfDisplay (dpy, screen))); + XtSetArg (al[4], XtNheight, HeightOfScreen (ScreenOfDisplay (dpy, screen))); + XtSetValues (app_shell, al, countof (al)); XtRealizeWidget (app_shell); } -#ifdef HAVE_SESSION + +#ifdef HAVE_WMCOMMAND { int new_argc; char **new_argv; @@ -552,7 +704,7 @@ x_init_device (struct device *d, Lisp_Object props) XSetCommand (XtDisplay (app_shell), XtWindow (app_shell), new_argv, new_argc); free_argc_argv (new_argv); } -#endif /* HAVE_SESSION */ +#endif /* HAVE_WMCOMMAND */ #ifdef HAVE_OFFIX_DND @@ -593,8 +745,8 @@ x_finish_init_device (struct device *d, Lisp_Object props) static void x_mark_device (struct device *d, void (*markobj) (Lisp_Object)) { - ((markobj) (DEVICE_X_WM_COMMAND_FRAME (d))); - ((markobj) (DEVICE_X_DATA (d)->x_keysym_map_hashtable)); + markobj (DEVICE_X_WM_COMMAND_FRAME (d)); + markobj (DEVICE_X_DATA (d)->x_keysym_map_hash_table); } @@ -614,7 +766,7 @@ x_delete_device (struct device *d) Lisp_Object device; Display *display; #ifdef FREE_CHECKING - extern void (*__free_hook)(); + extern void (*__free_hook) (void *); int checking_free; #endif @@ -637,6 +789,12 @@ x_delete_device (struct device *d) if (DEVICE_X_DATA (d)->x_keysym_map) XFree ((char *) DEVICE_X_DATA (d)->x_keysym_map); + if (DEVICE_XT_APP_SHELL (d)) + { + XtDestroyWidget (DEVICE_XT_APP_SHELL (d)); + DEVICE_XT_APP_SHELL (d) = NULL; + } + XtCloseDisplay (display); DEVICE_X_DISPLAY (d) = 0; #ifdef FREE_CHECKING @@ -915,7 +1073,7 @@ x_IO_error_handler (Display *disp) DEVICE_X_BEING_DELETED (d) = 1; Fthrow (Qtop_level, Qnil); - RETURN_NOT_REACHED (0); + return 0; /* not reached */ } DEFUN ("x-debug-mode", Fx_debug_mode, 1, 2, 0, /* @@ -1448,8 +1606,8 @@ Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in return XStringToKeysym (keysym_ext) ? Qt : Qnil; } -DEFUN ("x-keysym-hashtable", Fx_keysym_hashtable, 0, 1, 0, /* -Return a hashtable which contains a hash key for all keysyms which +DEFUN ("x-keysym-hash-table", Fx_keysym_hash_table, 0, 1, 0, /* +Return a hash table which contains a hash key for all keysyms which name keys on the keyboard. See `x-keysym-on-keyboard-p'. */ (device)) @@ -1458,7 +1616,7 @@ name keys on the keyboard. See `x-keysym-on-keyboard-p'. if (!DEVICE_X_P (d)) signal_simple_error ("Not an X device", device); - return DEVICE_X_DATA (d)->x_keysym_map_hashtable; + return DEVICE_X_DATA (d)->x_keysym_map_hash_table; } DEFUN ("x-keysym-on-keyboard-sans-modifiers-p", Fx_keysym_on_keyboard_sans_modifiers_p, @@ -1480,7 +1638,7 @@ The two names differ in capitalization and underscoring. signal_simple_error ("Not an X device", device); return (EQ (Qsans_modifiers, - Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASHTABLE (d), Qnil)) ? + Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASH_TABLE (d), Qnil)) ? Qt : Qnil); } @@ -1502,7 +1660,7 @@ The two names differ in capitalization and underscoring. if (!DEVICE_X_P (d)) signal_simple_error ("Not an X device", device); - return (NILP (Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASHTABLE (d), Qnil)) ? + return (NILP (Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASH_TABLE (d), Qnil)) ? Qnil : Qt); } @@ -1635,6 +1793,69 @@ Release a keyboard grab made with `x-grab-keyboard'. return Qnil; } +DEFUN ("x-get-font-path", Fx_get_font_path, 0, 1, 0, /* +Get the X Server's font path. + +See also `x-set-font-path'. +*/ + (device)) +{ + Display *dpy = get_x_display (device); + int ndirs_return; + CONST char **directories = (CONST char **) XGetFontPath (dpy, &ndirs_return); + Lisp_Object font_path = Qnil; + + if (!directories) + signal_simple_error ("Can't get X font path", device); + + while (ndirs_return--) + font_path = Fcons (build_ext_string (directories[ndirs_return], + FORMAT_FILENAME), font_path); + + return font_path; +} + +DEFUN ("x-set-font-path", Fx_set_font_path, 1, 2, 0, /* +Set the X Server's font path to FONT-PATH. + +There is only one font path per server, not one per client. Use this +sparingly. It uncaches all of the X server's font information. + +Font directories should end in the path separator and should contain +a file called fonts.dir usually created with the program mkfontdir. + +Setting the FONT-PATH to nil tells the X server to use the default +font path. + +See also `x-get-font-path'. +*/ + (font_path, device)) +{ + Display *dpy = get_x_display (device); + Lisp_Object path_entry; + CONST char **directories; + int i=0,ndirs=0; + + EXTERNAL_LIST_LOOP (path_entry, font_path) + { + CHECK_STRING (XCAR (path_entry)); + ndirs++; + } + + directories = alloca_array (CONST char *, ndirs); + + EXTERNAL_LIST_LOOP (path_entry, font_path) + { + GET_C_STRING_FILENAME_DATA_ALLOCA (XCAR (path_entry), directories[i++]); + } + + expect_x_error (dpy); + XSetFontPath (dpy, (char **) directories, ndirs); + signal_if_x_error (dpy, 1/*resumable_p*/); + + return Qnil; +} + /************************************************************************/ /* initialization */ @@ -1654,7 +1875,7 @@ syms_of_device_x (void) DEFSUBR (Fx_server_vendor); DEFSUBR (Fx_server_version); DEFSUBR (Fx_valid_keysym_name_p); - DEFSUBR (Fx_keysym_hashtable); + DEFSUBR (Fx_keysym_hash_table); DEFSUBR (Fx_keysym_on_keyboard_p); DEFSUBR (Fx_keysym_on_keyboard_sans_modifiers_p); @@ -1663,6 +1884,9 @@ syms_of_device_x (void) DEFSUBR (Fx_grab_keyboard); DEFSUBR (Fx_ungrab_keyboard); + DEFSUBR (Fx_get_font_path); + DEFSUBR (Fx_set_font_path); + defsymbol (&Qx_error, "x-error"); defsymbol (&Qinit_pre_x_win, "init-pre-x-win"); defsymbol (&Qinit_post_x_win, "init-post-x-win");