Back to index

im-sdk  12.3.91
guiIMStsNothing.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 "xiiimp.h"
00043 #include "guiIMSts.h"
00044 #include "XimpIm.h"
00045 #include "iiimpIM.h"
00046 #include "xfactory.h"
00047 #include "trace_message.h"
00048 
00049 static XicCommon Focussed_IC = 0;
00050 static StatusWin Focussed_STATUS = 0;
00051 
00052 static void set_window(XicCommon ic, XPointer call_data);
00053 
00054 static Bool
00055 track_client_window_move (Display *d, Window w,
00056                        XEvent *ev, XPointer client_data)
00057 {
00058   XicCommon ic = (XicCommon)client_data;
00059 
00060   if (ic && ic->gui_icpart)
00061     set_window(ic, 0);
00062   else
00063     _XUnregisterFilter(d, w, track_client_window_move, (XPointer)ic);
00064 
00065   return False;
00066 }
00067 
00068 /* ChangeStatus Methods */
00069 static void
00070 create(XicCommon ic, XPointer call_data) {
00071   StatusWin status = (StatusWin)(ic->gui_icpart->status);
00072   Display *display = ic->core.im->core.display;
00073   XWindowAttributes attr;
00074 
00075 #ifdef DISABLE_IMSTATUS_FOR_NON_UTF8_LOCALES
00076   char *client_type = XIM_IIIMP(ic->core.im, client_type);
00077   if (client_type && strcmp(client_type, "IIIMX XIM Server") == 0)
00078     return;
00079 #endif
00080 
00081   if (!(ic->ximp_icpart->value_mask & XIMP_CLIENT_WIN)) return;
00082 
00083   if (!status) {
00084     SetupStatusExt(ic);
00085     status = (StatusWin)(ic->gui_icpart->status);
00086   }
00087 
00088   if (status->parent != 0) {
00089     /* status window is already created  */
00090     return;
00091   }
00092   XGetWindowAttributes(display, 
00093                      ic->core.client_window,
00094                      &attr);
00095   SetupStatusWindow(ic, RootWindow(display,
00096                                XScreenNumberOfScreen(attr.screen)));
00097 
00098   {
00099     Window client_toplevel = None;
00100     client_toplevel = XFactoryGetToplevelWindow(display,
00101                                           ic->core.client_window);
00102     if (client_toplevel) {
00103       XimCommon im = (XimCommon)ic->core.im;
00104       if (XIM_IS_IIIMP(im)) {
00105        char *client_type = XIM_IIIMP(im, client_type);
00106        if (client_type && strcmp(client_type, "IIIMX XIM Server") == 0) {
00107          XSelectInput(display, client_toplevel,
00108                      attr.your_event_mask | StructureNotifyMask);
00109        }
00110       }
00111       _XRegisterFilterByType(display, client_toplevel,
00112                           ConfigureNotify, ConfigureNotify,
00113                           track_client_window_move, (XPointer)ic);
00114     }
00115   }
00116   return;
00117 }
00118 
00119 static void
00120 set_window(XicCommon ic, XPointer call_data) {
00121   StatusWin status = (StatusWin)(ic->gui_icpart->status);
00122   Display *display = ic->core.im->core.display;
00123 
00124   TRACE_MESSAGE('s', ("iiimp_set_window: status=0x%08x window=0x%08x\n",
00125                     status, status ? status->window : 0));
00126   if (!status) {
00127     create(ic, NULL);
00128     status = (StatusWin)(ic->gui_icpart->status);
00129     if (!status) return;
00130   }
00131 
00132   if (!Focussed_IC) {
00133     Focussed_IC = (XicCommon)ic;
00134     Focussed_STATUS = (StatusWin)status;
00135   }
00136   if (XIMP_CHK_FOCUSWINMASK(ic) && (ic != Focussed_IC)) {
00137     if (Focussed_STATUS->window) {
00138       XWindowAttributes tswin_att;
00139       if (XGetWindowAttributes(display,Focussed_STATUS->window,&tswin_att) > 0) {
00140        if (tswin_att.map_state != IsUnmapped) {
00141          XUnmapWindow(display,Focussed_STATUS->window);
00142           Focussed_IC = (XicCommon)ic;
00143           Focussed_STATUS = (StatusWin)status;   
00144        }
00145       }
00146     }
00147   }
00148 
00149   if (status->window) {
00150     XWindowAttributes win_att;
00151     Window frame_window;
00152     int x_margin, y_margin;
00153 
00154     frame_window = XFactoryGetFrameWindow(display,
00155                                      ic->core.client_window);
00156 
00157     if (XGetWindowAttributes(display, frame_window,
00158                           &win_att) > 0) {
00159       int x, y, width = 0, height = 0;
00160       XSizeHints  hints;
00161       XWMHints wm_hints;
00162       CacheRec *status_cache = (CacheRec*)&(status->status_cache);
00163       char * status_string;
00164       int len;
00165       extern char * MergeStatus(XicCommon ic);
00166 
00167       x = win_att.x;
00168       y = win_att.y;
00169       y += win_att.height;
00170 
00171       if (!status->fontset)
00172        SetStatusFont(ic, NULL);
00173 
00174       if (!status->fontset)
00175        return;
00176 
00177       status_string = MergeStatus(ic);
00178       len = ((NULL == status_string) ? 0 : strlen(status_string));
00179       if (0 < len) {
00180        XFontSetExtents *fse;
00181        fse = XExtentsOfFontSet(status->fontset);
00182        width = XmbTextEscapement(status->fontset,
00183                               status_string,
00184                               len);
00185        height = fse->max_logical_extent.height;
00186       }
00187       Xfree(status_string);
00188       /* avoid creating 0 width/height or too large status window */
00189       if (width == 0 || width > 1000) width = 100;
00190       if (height == 0 || height > 1000) height = 15;
00191 
00192       /* calculate margin */
00193       x_margin = 0;
00194       y_margin = height/5;
00195 
00196       width += x_margin * 2;
00197 
00198       status_cache = (CacheRec*)&(status->status_cache);
00199       if (status_cache->win_x == x &&
00200          status_cache->win_y == y &&
00201          status_cache->win_width == width &&
00202          status_cache->win_height == height) {
00203        return;
00204       }
00205 
00206       status->x = x_margin;
00207       status->y = height - y_margin;
00208 
00209       hints.flags = PSize | PPosition;
00210       hints.x = x;
00211       hints.y = y;
00212       hints.width  = width;
00213       hints.height = height;
00214       XSetWMNormalHints(display, status->window, &hints);
00215       wm_hints.flags = InputHint;
00216       wm_hints.input = False;
00217       XSetWMHints(display, status->window, &wm_hints);
00218       XFactoryValidateCoordinates(ic->core.im->core.display,
00219                               status->window,
00220                               &x, &y);
00221       XMoveResizeWindow(ic->core.im->core.display,
00222                      status->window,
00223                      x, y, width, height);
00224       /* data cache */
00225       status_cache->win_x = x;
00226       status_cache->win_y = y;
00227       status_cache->win_width = width;
00228       status_cache->win_height = height;
00229     }
00230   }
00231   return;
00232 }
00233 
00234 static void
00235 HideStatus(XicCommon ic, XPointer call_data) {
00236   StatusWin status;
00237 
00238   if (!ic->gui_icpart) return;
00239 
00240   status = (StatusWin)(ic->gui_icpart->status);
00241 
00242   if (!status) return;
00243 
00244 #ifndef       linux
00245  {
00246    XWindowAttributes cwin_att;
00247    if (XGetWindowAttributes(ic->core.im->core.display,
00248                             ic->core.client_window,
00249                             &cwin_att)) {
00250      if (cwin_att.map_state != IsUnmapped) return;
00251    }
00252  }
00253 #endif
00254 
00255   if (XIMP_CHK_FOCUSWINMASK(ic)){
00256     XUnmapWindow(ic->core.im->core.display, status->window);
00257   }
00258 }
00259 
00260 static StatusCB status_nothing_methods[] = {
00261   create,                   /* STATUS_CREATE */
00262   set_window,               /* STATUS_WIN */
00263   SetStatusForeground,             /* STATUS_FG */
00264   SetStatusBackground,             /* STATUS_BG */
00265   SetStatusFont,            /* STATUS_FONT */
00266   StatusStart,                     /* STATUS_START */
00267   StatusDrawText,           /* STATUS_DRAW */
00268   StatusDone,               /* STATUS_DONE */
00269   DestroyStatus,            /* STATUS_DESTROY */
00270   HideStatus                /* STATUS_HIDE */
00271 };
00272 
00273 /* Public function */
00274 void
00275 ChangeStatusNothing(XIC xic, StatusAttr reason, XPointer call_data) {
00276   XicCommon ic = (XicCommon)xic;
00277 
00278 #ifdef linux
00279   if(getenv("HTT_DISABLE_STATUS_WINDOW")){
00280     return;
00281   }
00282 #endif
00283 
00284   if (reason == STATUS_DESTROY) {
00285     Focussed_IC=(XicCommon)NULL;
00286     Focussed_STATUS = (StatusWin)NULL;
00287   }
00288 
00289   if (reason > STATUS_HIDE) return;
00290 
00291   status_nothing_methods[reason](ic, call_data);
00292   return;
00293 }
00294