Back to index

im-sdk  12.3.91
xfactory.c
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 <X11/Xlib.h>
00043 #include <X11/Xatom.h>             /* Required for XA_ATOM */
00044 #ifndef linux
00045 #include <Xm/MwmUtil.h>
00046 #endif
00047 #include "guiIM.h"
00048 #include "xfactory.h"
00049 
00050 #define PROP_WM_STATE_ELEMENTS 2
00051 
00052 typedef struct _PropWMState {
00053     unsigned long state;
00054     unsigned long ion;
00055 
00056 } PropWMState;
00057 
00058 static Bool
00059 GetWMState(Display *display, Window window) {
00060     int ret_val;
00061     PropWMState *property = NULL;
00062     Atom actual_type;
00063     int actual_format;
00064     unsigned long nitems;
00065     unsigned long leftover;
00066     Atom wm_state = XInternAtom(display, "WM_STATE", True);
00067 
00068     ret_val = XGetWindowProperty(display, window, wm_state,
00069                              0L, PROP_WM_STATE_ELEMENTS,
00070                              False, wm_state,
00071                              &actual_type, &actual_format,
00072                              &nitems, &leftover,
00073                              (unsigned char **)&property);
00074     if (!((ret_val == Success) && (actual_type == wm_state) &&
00075          (nitems == PROP_WM_STATE_ELEMENTS))) {
00076        /*
00077         * The property could not be retrieved or is not correctly set up.
00078         */
00079        if (property) {
00080            XFree((char *)property);
00081        }
00082        return False;
00083     }
00084     if (property) {
00085        XFree((char *)property);
00086     }
00087     return True;
00088 }
00089 
00090 /* Refer to /usr/dt/include/Xm/MwmUtil.h */
00091 static Atom mwm_del_atom = (Atom)0;
00092 
00093 /* Refer to OlClients.h */
00094 static Atom ol_del_atom = (Atom)0;
00095 static Atom ol_del_atom_list[3];
00096 static int ol_atom_inx = 0;
00097 
00098 static void getAtoms(Display *display) {
00099     if (!mwm_del_atom) {
00100        mwm_del_atom = XInternAtom(display, "_MOTIF_WM_HINTS", True);
00101     }
00102     if (!ol_del_atom) {
00103         ol_atom_inx = 0;
00104        ol_del_atom = XInternAtom(display, "_OL_DECOR_DEL", True);
00105        ol_del_atom_list[ol_atom_inx++] =
00106            XInternAtom(display, "_OL_DECOR_RESIZE", True);
00107        ol_del_atom_list[ol_atom_inx++] =
00108            XInternAtom(display, "_OL_DECOR_HEADER", True);
00109     }
00110 }
00111 
00112 static void
00113 remove_decoration(Display * display, Window window,
00114                 int decoration)
00115 {
00116     struct _mwmhints {
00117        unsigned long flags, func, deco;
00118        long    input_mode;
00119        unsigned long status;
00120     } mwm_del_hints;
00121     
00122     getAtoms(display);
00123 
00124     if (mwm_del_atom != None) {
00125        mwm_del_hints.flags = 1L << 1; /* flags for decoration */
00126        mwm_del_hints.deco = decoration;
00127        XChangeProperty(display, window,
00128                      mwm_del_atom, mwm_del_atom, 32,
00129                      PropModeReplace,
00130                      (unsigned char *)&mwm_del_hints, 5);
00131     }
00132     if (ol_del_atom != None) {
00133         XChangeProperty(display, window, ol_del_atom, XA_ATOM, 32,
00134                      PropModeReplace, (unsigned char*)ol_del_atom_list,
00135                      ol_atom_inx);
00136     }
00137 
00138     {
00139       /* 4344419 */
00140       /* window title is attached while using enlightenment on linux */
00141       /* need to disable [x] (dismiss window) function */
00142       Atom wm_window_protocols[1];
00143       Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
00144       wm_window_protocols[0] = wm_delete_window;
00145       XSetWMProtocols(display, window, wm_window_protocols, 1);
00146     }
00147     {
00148       /* 4390729 */
00149       /* window should not grab any input focus */
00150       XWMHints wm_hints;
00151       wm_hints.flags = InputHint;
00152       wm_hints.input = False;
00153       XSetWMHints(display, window, &wm_hints);
00154     }
00155     {
00156       Atom net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);
00157       Atom net_wm_state_skip_taskbar = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False);
00158       Atom net_wm_state_prop[1];
00159 
00160       net_wm_state_prop[0] = net_wm_state_skip_taskbar;
00161       XChangeProperty(display, window, net_wm_state, XA_ATOM, 32,
00162                     PropModeReplace, (unsigned char *) net_wm_state_prop, 1);
00163     }
00164 }
00165 
00166 /*
00167 #define MWM_DECOR_ALL              (1L << 0)
00168 #define MWM_DECOR_BORDER    (1L << 1)
00169 #define MWM_DECOR_RESIZEH   (1L << 2)
00170 #define MWM_DECOR_TITLE            (1L << 3)
00171 #define MWM_DECOR_MENU             (1L << 4)
00172 #define MWM_DECOR_MINIMIZE  (1L << 5)
00173 #define MWM_DECOR_MAXIMIZE  (1L << 6)
00174 */
00175 
00176 void
00177 XFactoryRemoveDecoration(Display *display, Window window) {
00178   remove_decoration(display, window, 1L << 1); /* set Border only */
00179   return;
00180 }
00181 
00182 void
00183 XFactoryRemoveDecorationExceptTitle(Display *display, Window window) {
00184   remove_decoration(display, window, 1L << 1 | 1L << 3); /* set Border only */
00185   return;
00186 }
00187 
00188 void
00189 XFactoryRemoveAllDecoration(Display *display, Window window) {
00190   remove_decoration(display, window, 0); /* set nothing */
00191   return;
00192 }
00193 
00194 void
00195 XFactoryRemoveMenu(Display *display, Window window) {
00196   remove_decoration(display, window, 1L << 1 | 1L << 3);
00197   return;
00198 }
00199 
00200 void
00201 XFactoryRemoveBorder(Display *display, Window window) {
00202   /* set all the flags other than border */
00203   remove_decoration(display, window,
00204                   1L << 2 | 1L << 3 | 1L << 4 | 1L << 5 | 1L << 6);
00205   return;
00206 }
00207 
00208 Window
00209 XFactoryGetFrameWindow(Display *display, Window window) {
00210     Window top_win;
00211     Window current_window = window;
00212 
00213     for (;;) {
00214         Window root_return, parent_return, *child_return = NULL;
00215         unsigned int nchild_return;
00216         top_win = current_window;
00217         if (XQueryTree(display, current_window,
00218                        &root_return, &parent_return,
00219                        &child_return, &nchild_return) == 0) {
00220             if (child_return) XFree(child_return);
00221             break;
00222         }
00223         if (child_return) XFree(child_return);
00224         current_window = parent_return;
00225         if (parent_return == root_return) break;
00226     }
00227     return top_win;
00228 }
00229 
00230 Window
00231 XFactoryGetToplevelWindow(Display *display, Window window) {
00232     Window root_return, parent_return, *child_return = NULL, current_window;
00233     unsigned int nchild_return;
00234 
00235     if (GetWMState(display, window)) return window;
00236 
00237     current_window = window;
00238     for (;;) {
00239        if (XQueryTree(display, current_window,
00240                      &root_return, &parent_return,
00241                      &child_return, &nchild_return) == 0) {
00242            if (child_return) XFree(child_return);
00243            break;
00244        }
00245        if (child_return) XFree(child_return);
00246        if (GetWMState(display, parent_return)) {
00247            return parent_return;
00248        }
00249        if (parent_return == root_return) {
00250            return current_window;
00251        }
00252        current_window = parent_return;
00253     }
00254     /* error */
00255     return window;
00256 }
00257 
00258 void
00259 XFactoryGetLocationOnScreen(Display *display, Window window,
00260                          int x, int y, XPoint *point) {
00261   XWindowAttributes attr;
00262   Window child;
00263   int new_x, new_y;
00264 
00265   if (XGetWindowAttributes(display, window, &attr) > 0) {
00266     XTranslateCoordinates(display, window,
00267                        RootWindow(display,
00268                                  XScreenNumberOfScreen(attr.screen)),
00269                        x, y,
00270                        &new_x, &new_y, &child);
00271 
00272     point->x = new_x;
00273     point->y = new_y;
00274   }
00275   return;
00276 }
00277 
00278 Window
00279 XFactoryCreateIMWindow(Display *display, Window parent,
00280                      Window transient_win,
00281                      int x, int y,
00282                      unsigned int width, unsigned int height,
00283                      unsigned long bg, long event_mask,
00284                      XIMFilter filters, int count) {
00285   Window win;
00286   int i;
00287   Window top_win;
00288 
00289   if (width <= 0) width = 1;
00290   if (height <= 0) height = 1;
00291 
00292   win = XCreateSimpleWindow(display, parent,
00293                          x, y, width, height,
00294                          0, /* border width: who cares? */
00295                          0, /* border color */
00296                          bg);
00297   if (!win) return 0;
00298 
00299   XFactoryRemoveDecoration(display, win);
00300 
00301   /* query toplevel window */
00302   top_win = XFactoryGetToplevelWindow(display, transient_win);
00303   XSetTransientForHint(display, win, top_win);
00304 
00305   XSelectInput(display, win, event_mask);
00306 
00307   for (i = 0; i < count; i++) {
00308     _XRegisterFilterByType(display, win,
00309                         filters[i].type, filters[i].type,
00310                         filters[i].filter,
00311                         (XPointer)filters[i].client_data);
00312   }
00313   return win;
00314 }
00315 
00316 void
00317 XFactoryAdjustPlacementInsideScreen(Display * dpy, Window win,
00318                                 int x, int y,
00319                                 int width, int height,
00320                                 int * ret_x, int * ret_y) {
00321   XWindowAttributes attr;
00322   int dpy_width;
00323   int dpy_height;
00324   int screen_num;
00325 
00326   width += 20;
00327   height += 20;
00328 
00329   if (XGetWindowAttributes(dpy, win, &attr) > 0) {
00330     screen_num = XScreenNumberOfScreen(attr.screen);
00331   } else {
00332     screen_num = 0;
00333   }
00334 
00335   dpy_width = DisplayWidth(dpy, screen_num);
00336   dpy_height = DisplayHeight(dpy, screen_num);
00337 
00338   if (dpy_width < (x + width)) {
00339     if (width <= dpy_width) {
00340       *ret_x = (dpy_width - width);
00341     } else {
00342       *ret_x = 0;
00343     }
00344   } else {
00345     *ret_x = x;
00346   }
00347 
00348   if (dpy_height < (y + height)) {
00349     if (height <= dpy_height) {
00350       *ret_y = (dpy_height - height);
00351     } else {
00352       *ret_y = 0;
00353     }
00354   } else {
00355     *ret_y = y;
00356   }
00357 }
00358 
00359 int
00360 XFactoryResizeWindowInsideScreen(Display * display, Window w,
00361                              unsigned int width, unsigned int height) {
00362   XWindowAttributes attr;
00363   int x;
00364   int y;
00365 
00366   if (XGetWindowAttributes(display, w, &attr) > 0) {
00367     XFactoryAdjustPlacementInsideScreen(display, w, attr.x, attr.y,
00368                                    width, height, &x, &y);
00369     if ((attr.x == x) && (attr.y == y)) {
00370       XResizeWindow(display, w, width, height);
00371     } else {
00372       XMoveResizeWindow(display, w, x, y, width, height);
00373     }
00374   }
00375   return 0;
00376 }
00377 
00378 int
00379 XFactoryMoveResizeWindowInsideScreen(Display * display, Window w,
00380                                  int x, int y,
00381                                  unsigned int width, unsigned int height) {
00382   XFactoryAdjustPlacementInsideScreen(display, w, x, y,
00383                                   width, height, &x, &y);
00384   XMoveResizeWindow(display, w, x, y, width, height);
00385 
00386   return 0;
00387 }
00388 
00389 int
00390 XFactoryMoveWindowInsideScreen(Display * display, Window w,
00391                             int x, int y) {
00392   XWindowAttributes attr;
00393 
00394   if (XGetWindowAttributes(display, w, &attr) > 0) {
00395     XFactoryAdjustPlacementInsideScreen(display, w, x, y,
00396                                    attr.width, attr.height,
00397                                    &x, &y);
00398     XMoveWindow(display, w, x, y);
00399   }
00400 
00401   return 0;
00402 }
00403 
00404 int 
00405 XFactoryValidateCoordinates(Display * display, Window w,
00406                                int *x, int *y) {
00407   XWindowAttributes attr;
00408   int newx, newy;
00409   if (XGetWindowAttributes(display, w, &attr) > 0) {
00410     XFactoryAdjustPlacementInsideScreen(display, w, *x, *y,
00411                                         attr.width, attr.height,
00412                                         &newx, &newy);
00413     *x = newx;
00414     *y = newy;
00415   }
00416   return 0;
00417 }
00418 
00419 /* 4378199: Linux Htt: can not operate after WMDoc client is
00420                               closed on VineLinux2.0
00421 
00422    Need to check client_window is valid or not before creating
00423    status, preedit and lookup
00424 */
00425 Bool
00426 XFactoryCheckIMWindow(Display* display, Window window) {
00427   Window root;
00428   int ax, ay;
00429   unsigned int awidth, aheight, aborder, adepth;
00430   int s;
00431 
00432   if (!window) return False;
00433 
00434   s = XGetGeometry(display, window, &root, &ax, &ay,
00435                 &awidth, &aheight, &aborder, &adepth);
00436 
00437   return s;
00438 }
00439 
00440 static XFontSet default_fontset = (XFontSet)0;
00441 static int ref_count = 0;
00442 
00443 XFontSet
00444 XFactoryCreateDefaultFontSet (Display *display, char *default_fontname)
00445 {
00446   char **missing_list;
00447   int missing_count;
00448   char *def_string;
00449   char *base_font_name;
00450 
00451   ref_count++;
00452 
00453   if (default_fontset)
00454     return default_fontset;
00455 
00456   if (default_fontname && default_fontname[0])
00457     {
00458       base_font_name = default_fontname;
00459       default_fontset = XCreateFontSet (display,
00460                                    base_font_name, &missing_list,
00461                                    &missing_count, &def_string);
00462     }
00463   if (default_fontset)
00464     return default_fontset;
00465 
00466   base_font_name = DEFAULT_FONT_NAME_CDE;
00467   default_fontset = XCreateFontSet (display,
00468                                 base_font_name, &missing_list,
00469                                 &missing_count, &def_string);
00470   if (default_fontset)
00471     return default_fontset;
00472 
00473   base_font_name = DEFAULT_FONT_NAME;
00474   default_fontset = XCreateFontSet (display,
00475                                 base_font_name, &missing_list,
00476                                 &missing_count, &def_string);
00477   return default_fontset;
00478 }
00479 
00480 void
00481 XFactoryFreeDefaultFontSet(Display *display)
00482 {
00483   if (--ref_count == 0)
00484     {
00485       if (default_fontset)
00486        XFreeFontSet (display, default_fontset);
00487       default_fontset = 0;
00488     }
00489   return;
00490 }