Back to index

im-sdk  12.3.91
Xfactory.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #include "Xfactory.hh"
00043 #include <X11/Xlib.h>
00044 #include <X11/Xatom.h>             /* Required for XA_ATOM */
00045 #ifdef DEBUG
00046 #include <stdio.h>
00047 #endif
00048 #include <stdlib.h>
00049 #include <string.h>
00050 
00051 extern "C" {
00052   extern void _XRegisterFilterByType(Display*, Window, int, int,
00053                            XIMFilter, XPointer);
00054   extern void _XUnregisterFilter(Display*, Window, XIMFilter, XPointer);
00055           }
00056 
00057 /* Refer to /usr/dt/include/Xm/MwmUtil.h */
00058 static Atom mwm_del_atom = (Atom)0;
00059 
00060 /* Refer to OlClients.h */
00061 static Atom ol_del_atom = (Atom)0;
00062 static Atom ol_del_atom_list[3];
00063 static int ol_atom_inx = 0;
00064 
00065 static void getAtoms(Display *display) {
00066   if (!mwm_del_atom) {
00067     mwm_del_atom = XInternAtom(display, "_MOTIF_WM_HINTS", True);
00068   }
00069   if (!ol_del_atom) {
00070     ol_del_atom = XInternAtom(display, "_OL_DECOR_DEL", True);
00071     ol_del_atom_list[ol_atom_inx++] =
00072       XInternAtom(display, "_OL_DECOR_RESIZE", True);
00073     ol_del_atom_list[ol_atom_inx++] =
00074       XInternAtom(display, "_OL_DECOR_HEADER", True);
00075   }
00076 }
00077 
00078 
00079 void
00080 XFactory::remove_decoration(Display *display, Window window) {
00081   const int decoration = (1L << 1);       /* set border only */
00082   struct _mwmhints {
00083     unsigned long flags, func, deco;
00084     long    input_mode;
00085     unsigned long status;
00086   } mwm_del_hints;
00087 
00088   getAtoms(display);
00089 
00090   if (mwm_del_atom != None) {
00091     mwm_del_hints.flags = 1L << 1; /* flags for decoration */
00092     mwm_del_hints.deco = decoration;
00093     XChangeProperty(display, window,
00094                   mwm_del_atom, mwm_del_atom, 32,
00095                   PropModeReplace,
00096                   (unsigned char *)&mwm_del_hints, 5);
00097   }
00098   if (ol_del_atom != None) {
00099     XChangeProperty(display, window, ol_del_atom, XA_ATOM, 32,
00100                   PropModeReplace, (unsigned char*)ol_del_atom_list,
00101                   ol_atom_inx);
00102   }
00103   return;
00104 }
00105 
00106 void
00107 XFactory::register_filter(Display *display, Window window,
00108                        int start_type, int end_type,
00109                        XIMFilter filter, XPointer call_data) {
00110   _XRegisterFilterByType(display, window, start_type,
00111                       end_type, filter, call_data);
00112   return;
00113 }
00114 
00115 void
00116 XFactory::unregister_filter(Display *display, Window window,
00117                          XIMFilter filter, XPointer call_data) {
00118   _XUnregisterFilter(display, window, filter, call_data);
00119   return;
00120 }
00121 
00122 FsSet XFactory::fs_list;
00123 
00124 XFontSet
00125 XFactory::create_fontset(Display *display, const char *name) {
00126   CompoundString font_name(name);
00127 
00128   FsSet fsp = fs_list;
00129   while (fsp) {
00130     if (fsp->fs_name.length() == font_name.length() &&
00131        fsp->fs_name == font_name) {
00132       fsp->ref_count++;
00133       return(fsp->fs);
00134     }
00135     fsp = fsp->next;
00136   }
00137   // not found
00138   char **missing_list;
00139   int missing_count;
00140   char *def_string;
00141   int fallback_flag = 0;
00142   XFontSet font_set = XCreateFontSet(display, (char*)font_name,
00143                                  &missing_list, &missing_count,
00144                                  &def_string);
00145   if (font_set == 0) {
00146     fallback_flag = 1;
00147   }
00148   if (missing_count > 0) {
00149     int list_ret;
00150     XFontStruct **struct_list = NULL;
00151     char **name_list = NULL;
00152     const char *cur_str = NULL;
00153     int i;
00154     list_ret = XFontsOfFontSet(font_set,
00155                             &struct_list, &name_list);
00156     cur_str = name;
00157     for (i = 0; i < list_ret && cur_str != NULL; ++i) {
00158       char *tmp_str;
00159       if (strncmp(cur_str, (const char*)name_list[i],
00160                 strlen(name_list[i])) != 0) {
00161        break;
00162       };
00163       tmp_str = (char *)strchr(cur_str, ',');
00164       if (tmp_str != NULL && strlen(tmp_str) > 1) {
00165        ++tmp_str;
00166       }
00167       else {
00168        tmp_str = NULL;
00169       }
00170       cur_str = (const char*)tmp_str;
00171     }
00172     if (i != list_ret || cur_str != NULL) {
00173 #ifdef DEBUG
00174       fprintf(stderr, "Warning\n");
00175       fprintf(stderr, " - FontSet creation partically failed due to missing character sets\n");
00176 #endif
00177       fallback_flag = 1;
00178     }
00179     XFreeStringList(missing_list);
00180   }
00181   if (fallback_flag == 1) {
00182     const char default_name[] = "-*-*-medium-r-normal-*-16-*-*-*-*-*-*-*";
00183 
00184     font_name = CompoundString(default_name);
00185     fsp = fs_list;
00186     while (fsp) {
00187       if (fsp->fs_name.length() == font_name.length() &&
00188          fsp->fs_name == font_name) {
00189        fsp->ref_count++;
00190        return(fsp->fs);
00191       }
00192       fsp = fsp->next;
00193     }
00194     font_set = XCreateFontSet(display, (char*)font_name,
00195                            &missing_list, &missing_count,
00196                            &def_string);
00197     if (font_set == 0) {
00198 #ifdef DEBUG
00199     fprintf(stderr, "Error\n");
00200     fprintf(stderr, " - Fallback FontSet creation failes\n");
00201 #endif
00202       return (XFontSet)0;
00203     }
00204     if (missing_count > 0) {
00205 #ifdef DEBUG
00206       fprintf(stderr, "Warning\n");
00207       fprintf(stderr, " - FontSet creation partically failed due to missing character sets\n");
00208 #endif
00209       XFreeStringList(missing_list);
00210     }
00211   }
00212   fsp = fs_list;
00213   while (fsp) {
00214     if (fsp->fs == 0 && fsp->ref_count == 0) break;
00215     fsp = fsp->next;
00216   }
00217   FsSet newfsp;
00218   if (fsp) {
00219     newfsp = fsp;    // found one
00220   } else {
00221     // create new list
00222     newfsp = new FsSetRec;
00223     if (!fs_list) {
00224       newfsp->next = (FsSet)0;
00225       fs_list = newfsp;
00226     } else {
00227       newfsp->next = fs_list;
00228       fs_list = newfsp;
00229     }
00230   }
00231   newfsp->fs = font_set;
00232   newfsp->fs_name = font_name;
00233   newfsp->ref_count = 1;
00234 
00235   return(newfsp->fs);
00236 }
00237 
00238 void
00239 XFactory::free_fontset(Display *display, XFontSet font_set) {
00240 
00241   if (!fs_list) return;
00242 
00243   FsSet fsp = fs_list;
00244   while (fsp) {
00245     if (font_set == fsp->fs)
00246       break;
00247     fsp = fsp->next;
00248   }
00249 
00250   if (!fsp || fsp->ref_count == 0) return;
00251 
00252   if (--(fsp->ref_count) > 0)   /* somebody else is still using */
00253     return;
00254 
00255   if (fsp->fs) {
00256     XFreeFontSet(display, fsp->fs);
00257     fsp->fs = 0;     //
00258   }
00259   return;
00260 }
00261 
00262 void
00263 XFactory::getLocationOnScreen(Display *display, Window window,
00264                            int x, int y, XPoint *point) {
00265   XWindowAttributes attr;
00266   Window child;
00267   int new_x, new_y;
00268 
00269   if (XGetWindowAttributes(display, window, &attr) > 0) {
00270     XTranslateCoordinates(display, window,
00271                        RootWindow(display,
00272                                  XScreenNumberOfScreen(attr.screen)),
00273                        x, y,
00274                        &new_x, &new_y, &child);
00275 
00276     point->x = new_x;
00277     point->y = new_y;
00278   }
00279   return;
00280 }
00281 
00282 #define PROP_WM_STATE_ELEMENTS 2
00283 
00284 typedef struct _PropWMState {
00285   unsigned long state;
00286   unsigned long ion;
00287 } PropWMState;
00288 
00289 static Bool
00290 GetWMState(Display *display, Window window) {
00291   int ret_val;
00292   PropWMState *property = NULL;
00293   Atom actual_type;
00294   int actual_format;
00295   unsigned long nitems;
00296   unsigned long leftover;
00297   Atom wm_state = XInternAtom(display, "WM_STATE", True);
00298 
00299   ret_val = XGetWindowProperty(display, window, wm_state,
00300                             0L, PROP_WM_STATE_ELEMENTS,
00301                             False, wm_state,
00302                             &actual_type, &actual_format,
00303                             &nitems, &leftover,
00304                             (unsigned char **)&property);
00305   if (!((ret_val == Success) && (actual_type == wm_state) &&
00306        (nitems == PROP_WM_STATE_ELEMENTS))) {
00307     /*
00308      * The property could not be retrieved or is not correctly set up.
00309      */
00310     if (property) {
00311       XFree((char*)property);
00312     }
00313     return False;
00314   }
00315   if (property) {
00316     XFree((char*)property);
00317   }
00318   return True;
00319 }
00320 
00321 Window
00322 XFactory::getToplevelWindow(Display *display, Window window) {
00323   Window root_return, parent_return, *child_return = NULL, current_window;
00324   unsigned int nchild_return;
00325 
00326   if (GetWMState(display, window)) return window;
00327 
00328   current_window = window;
00329   for (;;) {
00330     if (XQueryTree(display, current_window,
00331                  &root_return, &parent_return,
00332                  &child_return, &nchild_return) == 0) {
00333       if (child_return) XFree(child_return);
00334       break;
00335     }
00336     if (child_return) XFree(child_return);
00337     if (GetWMState(display, parent_return)) {
00338       return parent_return;
00339     }
00340     if (parent_return == root_return) {
00341       return current_window;
00342     }
00343     current_window = parent_return;
00344   }
00345   /* error */
00346   return window;
00347 }
00348 
00349 Window
00350 XFactory::getFrameWindow(Display *display, Window window) {
00351   Window top_win;
00352   Window current_window = window;
00353 
00354   for (;;) {
00355     Window root_return, parent_return, *child_return = NULL;
00356     unsigned int nchild_return;
00357     top_win = current_window;
00358     if (XQueryTree(display, current_window,
00359                  &root_return, &parent_return,
00360                  &child_return, &nchild_return) == 0) {
00361       if (child_return) XFree(child_return);
00362       break;
00363     }
00364     if (child_return) XFree(child_return);
00365     current_window = parent_return;
00366     if (parent_return == root_return) break;
00367   }
00368   return top_win;
00369 }
00370 
00371 int
00372 XFactory::xerror_handler(Display *display, XErrorEvent *ev) {
00373   char errmsg[80];
00374   Bool print_xerror = True;
00375 
00376   if (getenv("NOPRINT_XERROR")) print_xerror = False;
00377 
00378   if (print_xerror) {
00379     XGetErrorText(display, ev->error_code, errmsg, 80);
00380 #ifdef DEBUG
00381     fprintf(stderr, "Warning (X Error) -  %s\n", errmsg);
00382 #endif
00383   }
00384   return 0;
00385 }