Back to index

im-sdk  12.3.91
aux_ext.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 
00043 /*
00044  * "$Id: aux_ext.c,v 1.1.1.1.2.1 2001/03/15 07:52:21 himi Exp $"
00045  */
00046 
00047 #pragma ident "@(#)aux_ext.c 1.8   00/09/14 SMI"
00048 
00049 
00050 #include <locale.h>
00051 #include <stdlib.h>
00052 #include <stdio.h>
00053 #include <limits.h>
00054 
00055 #include <X11/Xmd.h>
00056 
00057 #include <Xm/Xm.h>
00058 #include <Xm/RowColumn.h>
00059 #include <Xm/Text.h>
00060 #include <Xm/PushB.h>
00061 
00062 #include "trace_message.h"
00063 
00064 
00065 #define HTT_AUX_EXT_NAME    "sample_ext"
00066 #define HTT_AUX_SO_NAME            "sample_so"
00067 #define HTT_AUX_PROP_NAME   "sample_prop"
00068 #define HTT_AUX_PROP1_NAME  "sample_prop1"
00069 
00070 
00071 Atom   aux_so_atom;
00072 Atom   aux_ext_atom;
00073 Atom   aux_prop_atom;
00074 Atom   aux_prop1_atom;
00075 
00076 Window        aux_window;
00077 
00078 Widget        toplevel;
00079 Widget        aux;
00080 Widget        input;
00081 Widget        button_text;
00082 Widget        button_message;
00083 Widget        button_quit;
00084 
00085 int           icid;
00086 int           imid;
00087 
00088 
00089 void
00090 ButtonTextCallback(Widget w, XtPointer client_data, XtPointer call_data)
00091 {
00092        XmAnyCallbackStruct *       cb;
00093        char *               p;
00094        Display *            display;
00095        Window               w_so;
00096        unsigned char        buf[1024];
00097        int                  size;
00098 
00099        display = XtDisplay(w);
00100        cb = (XmAnyCallbackStruct *)call_data;
00101        p = XmTextGetString((Widget)client_data);
00102 
00103        TRACE_MESSAGE('B', ("aux_ext:ButtonTextCallback: %d %s\n", cb->reason, p));
00104        
00105        if (None == (w_so = XGetSelectionOwner(display, aux_so_atom))) {
00106               TRACE_MESSAGE('b', ("aux_ext:ButtonTextCallback: no owner of %08x\n",
00107                                 aux_so_atom));
00108               return;
00109        }
00110 
00111        TRACE_MESSAGE('B', ("aux_ext:ButtonTextCallback: owner %08x\n", w_so));
00112 
00113        buf[0] = ((imid & 0xff00) >> 8);
00114        buf[1] = ((imid & 0x00ff) >> 0);
00115        buf[2] = ((icid & 0xff00) >> 8);
00116        buf[3] = ((icid & 0x00ff) >> 0);
00117        size = strlen(p);
00118        if (((sizeof (buf)) - 4) < size) {
00119               size = ((sizeof (buf)) - 4);
00120        }
00121        memcpy(buf + 4, p, size);
00122        XChangeProperty(display, w_so, aux_prop_atom, XA_STRING,
00123                      8, PropModeReplace, buf, size + 4);
00124 
00125        XFree(p);
00126 
00127        return;
00128 }
00129 
00130 
00131 void
00132 ButtonMessageCallback(Widget w, XtPointer client_data, XtPointer call_data)
00133 {
00134        Display *            display;
00135        Window               w_so;
00136        XClientMessageEvent  event;
00137 
00138        display = XtDisplay(w);
00139 
00140        if (None == (w_so = XGetSelectionOwner(display, aux_so_atom))) {
00141               TRACE_MESSAGE('m', ("aux_ext:ButtonMessageCallback: no owner of %08x\n",
00142                                 aux_so_atom));
00143               return;
00144        }
00145 
00146        event.type = ClientMessage;
00147        event.serial = 0;
00148        event.send_event = True;
00149        event.display = display;
00150        event.window = w_so;
00151        event.message_type = XA_STRING;
00152        event.format = 8;
00153        event.data.b[0] = ((imid & 0xff00) >> 8);
00154        event.data.b[1] = ((imid & 0x00ff) >> 0);
00155        event.data.b[2] = ((icid & 0xff00) >> 8);
00156        event.data.b[3] = ((icid & 0x00ff) >> 0);
00157        event.data.b[4] = 'h';
00158        event.data.b[5] = 'o';
00159        event.data.b[6] = 'g';
00160        event.data.b[7] = 'e';
00161        event.data.b[8] = '\0';
00162 
00163        XSendEvent(display, w_so, True, 0, (XEvent *)(&event));
00164 }
00165 
00166 
00167 void
00168 ButtonQuitCallback(Widget w, XtPointer client_data, XtPointer call_data)
00169 {
00170        Display *            display;
00171        Window               w_so;
00172        XClientMessageEvent  event;
00173        pid_t                pid;
00174 
00175        display = XtDisplay(w);
00176 
00177        if (None == (w_so = XGetSelectionOwner(display, aux_so_atom))) {
00178               TRACE_MESSAGE('m', ("aux_ext:ButtonMessageCallback: no owner of %08x\n",
00179                                 aux_so_atom));
00180        } else {
00181               event.type = ClientMessage;
00182               event.serial = 0;
00183               event.send_event = True;
00184               event.display = display;
00185               event.window = w_so;
00186               event.message_type = aux_so_atom;
00187               event.format = 32;
00188               event.data.l[0] = 0;
00189 
00190               XSendEvent(display, w_so, True, 0, (XEvent *)(&event));
00191               XFlush(display);
00192        }
00193 
00194        exit(1);
00195 }
00196 
00197 
00198 void
00199 ProcessInitialPropertyNotify(void)
00200 {
00201        Display *            display;
00202        long                 long_length;
00203        Atom                 actual_type_return;
00204        int                  actual_format_return;
00205        unsigned long        nitem_return;
00206        unsigned long        bytes_after_return;
00207        unsigned char *             prop_return;
00208        int                  r;
00209        XTextProperty        text_prop;
00210        Window               w_so;
00211        char                 buf[1024];
00212        int                  len;
00213 
00214        display = XtDisplay(toplevel);
00215 
00216        if (None == (w_so = XGetSelectionOwner(display, aux_so_atom))) {
00217               TRACE_MESSAGE('I', ("aux_ext:ProcessInitialPropertyNotify: no owner of %08x\n",
00218                                 aux_so_atom));
00219               return;
00220        }
00221 
00222        TRACE_MESSAGE('I', ("aux_ext:ProcessInitialPropertyNotify: %08x %08x %08x\n",
00223                          display, w_so, aux_prop_atom));
00224 
00225        r = XGetWindowProperty(display, w_so,
00226                             aux_prop1_atom, 0, INT_MAX, True,
00227                             AnyPropertyType, &actual_type_return,
00228                             &actual_format_return, &nitem_return,
00229                             &bytes_after_return, &prop_return);
00230        if (Success != r) {
00231               TRACE_MESSAGE('P', ("aux_ext:ProcessInitialPropertyNotify: Fail\n"));
00232               return;
00233        }
00234 
00235        TRACE_MESSAGE('P',
00236                     ("aux_ext:ProcessInitialPropertyNotify: %x\n", actual_format_return));
00237        switch (actual_type_return) {
00238        case XA_STRING:
00239               TRACE_MESSAGE('P',
00240                            ("aux_ext:ProcessInitialPropertyNotify: \"%.*s\"\n",
00241                             nitem_return, prop_return));
00242               imid = *((CARD16 *)(prop_return + 0));
00243               icid = *((CARD16 *)(prop_return + 2));
00244               TRACE_MESSAGE('P', ("aux_ext:ProcessInitialPropertyNotify: imid=%08x icid=%08x\n",
00245                                 imid, icid));
00246               len = (((nitem_return - 4) < (sizeof (buf))) ?
00247                      (nitem_return - 4) : ((sizeof (buf)) - 1));
00248               memcpy(buf, prop_return + 4, len);
00249               buf[len] = '\0';
00250               XmTextSetString(input, buf);
00251 
00252               break;
00253        case XA_INTEGER:
00254               break;
00255        }
00256 
00257        XFree(prop_return);
00258        return;
00259 }
00260 
00261 
00262 void
00263 ProcessPropertyNotify(Widget w, XEvent * event)
00264 {
00265        Display *            display;
00266        XPropertyEvent *     prop_event;
00267        long                 long_length;
00268        Atom                 actual_type_return;
00269        int                  actual_format_return;
00270        unsigned long        nitem_return;
00271        unsigned long        bytes_after_return;
00272        unsigned char *             prop_return;
00273        int                  r;
00274        XTextProperty        text_prop;
00275        char                 buf[1024];
00276        int                  len;
00277 
00278        prop_event = (XPropertyEvent *)event;
00279 
00280        display = XtDisplay(w);
00281 
00282        if ((prop_event->window != aux_window) ||
00283            (prop_event->atom != aux_prop_atom)) {
00284               return;
00285        }
00286 
00287        TRACE_MESSAGE('P', ("aux_ext:ProcessPropertyNotify: %08x %08x %08x %08x %08x\n",
00288                          display,
00289                          aux_window, aux_prop_atom,
00290                          prop_event->window, prop_event->atom));
00291 
00292        r = XGetWindowProperty(display, aux_window,
00293                             aux_prop_atom, 0, INT_MAX, False,
00294                             AnyPropertyType, &actual_type_return,
00295                             &actual_format_return, &nitem_return,
00296                             &bytes_after_return, &prop_return);
00297        if (Success != r) {
00298               TRACE_MESSAGE('P', ("aux_ext:ProcessPropertyNotify: Fail\n"));
00299               return;
00300        }
00301 
00302        switch (actual_type_return) {
00303        case XA_STRING:
00304               TRACE_MESSAGE('P',
00305                            ("aux_ext:ProcessPropertyNotify: \"%.*s\"\n",
00306                             nitem_return, prop_return));
00307               imid = *((CARD16 *)(prop_return + 0));
00308               icid = *((CARD16 *)(prop_return + 2));
00309               TRACE_MESSAGE('P', ("aux_ext:ProcessPropertyNotify: imid=%08x icid=%08x\n",
00310                                 imid, icid));
00311               len = (((nitem_return - 4) < (sizeof (buf))) ?
00312                      (nitem_return - 4) : ((sizeof (buf)) - 1));
00313               memcpy(buf, prop_return + 4, len);
00314               buf[len] = '\0';
00315               if ('\0' != buf[0]) {
00316                      XmTextSetString(input, buf);
00317               }
00318               break;
00319        case XA_INTEGER:
00320               break;
00321        }
00322 
00323        XFree(prop_return);
00324        return;
00325 }
00326 
00327 
00328 void
00329 ProcessClientMessage(Widget w, XEvent * event)
00330 {
00331        Display *            display;
00332        XClientMessageEvent *       client_message;
00333        int                  im_id;
00334        int                  ic_id;
00335        Window               w_client;
00336        XPoint               point;
00337        XWindowAttributes    attr;
00338        int                  x;
00339        int                  y;
00340        Window               w_none;
00341 
00342        client_message = (XClientMessageEvent *)event;
00343 
00344        im_id = client_message->data.s[0];
00345        ic_id = client_message->data.s[1];
00346        w_client = client_message->data.l[1];
00347        point.x = client_message->data.l[2];
00348        point.y = client_message->data.l[3];
00349 
00350        display = XtDisplay(w);
00351 
00352        if ((client_message->message_type != aux_ext_atom) ||
00353            (client_message->window != aux_window)) {
00354               TRACE_MESSAGE('P', ("aux_ext:ProcessClientMessage "
00355                                 "%08x im=%d ic=%d w=%08x x=%d y=%d\n",
00356                                 aux_window,
00357                                 im_id, ic_id, w_client, point.x, point.y));
00358 
00359               return;
00360        }
00361 
00362        XGetWindowAttributes(display, w_client, &attr);
00363        XTranslateCoordinates(display, w_client, attr.root,
00364                            -(attr.border_width), -(attr.border_width),
00365                            &x, &y, &w_none);
00366 
00367        TRACE_MESSAGE('P', ("aux_ext:ProcessClientMessage "
00368                          "%08x im=%d ic=%d w=%08x x=%d+%d+%d y=%d+%d+%d\n",
00369                          aux_window,
00370                          im_id, ic_id, w_client,
00371                          attr.x, point.x,
00372                          attr.y, point.y));
00373 
00374        XtMoveWidget(w, x + point.x, y + point.y);
00375 
00376        return;
00377 }
00378 
00379 
00380 void
00381 AuxEventHandler(
00382        Widget        w,
00383        XtPointer     client_data,
00384        XEvent *      event,
00385        Boolean *     b)
00386 {
00387 
00388        TRACE_MESSAGE('E', ("aux_ext:AuxEventHandler: %d\n", event->type));
00389 
00390        switch (event->type) {
00391        case PropertyNotify:
00392               ProcessPropertyNotify(w, event);
00393               break;
00394        case ClientMessage:
00395               if (XtWindow(w) == aux_window) {
00396                      ProcessClientMessage(w, event);
00397               }
00398               break;
00399        default:
00400               break;
00401        }
00402 
00403        return;
00404 }
00405 
00406 
00407 int
00408 main(int argc, char ** argv)
00409 {
00410        XtAppContext  app;
00411        Display *     display;
00412        char          atom_name[1024];
00413 
00414        TRACE_MESSAGE_INIT("TRACE_AUX_EXT");
00415 
00416        setlocale(LC_ALL, NULL);
00417        XtSetLanguageProc(NULL, NULL, NULL);
00418 
00419        toplevel = XtAppInitialize(&app, "aux", NULL, 0,
00420                                &argc, argv, NULL, NULL, 0);
00421 
00422        display = XtDisplay(toplevel);
00423 
00424        sprintf(atom_name, "htt_%s_%s", *(argv + 0), HTT_AUX_EXT_NAME);
00425        aux_ext_atom = XInternAtom(display, atom_name, False);
00426        sprintf(atom_name, "htt_%s_%s", *(argv + 0), HTT_AUX_SO_NAME);
00427        aux_so_atom = XInternAtom(display, atom_name, False);
00428        sprintf(atom_name, "htt_%s_%s", *(argv + 0), HTT_AUX_PROP_NAME);
00429        aux_prop_atom = XInternAtom(display, atom_name, False);
00430        sprintf(atom_name, "htt_%s_%s", *(argv + 0), HTT_AUX_PROP1_NAME);
00431        aux_prop1_atom = XInternAtom(display, atom_name, False);
00432 
00433        if (None != XGetSelectionOwner(display, aux_ext_atom)) {
00434               fprintf(stderr, "%s\n", gettext("aux already exists"));
00435               exit(1);
00436        }
00437 
00438        aux = XtVaCreateManagedWidget("aux", xmRowColumnWidgetClass,
00439                                    toplevel, NULL, 0);
00440 
00441        input = XtCreateManagedWidget("input", xmTextWidgetClass,
00442                                   aux, NULL, 0);
00443 
00444        button_text = XtCreateManagedWidget("text", xmPushButtonWidgetClass,
00445                                        aux, NULL, 0);
00446 
00447        XtAddCallback(button_text, XmNarmCallback, ButtonTextCallback, input);
00448 
00449        button_message = XtCreateManagedWidget("message",
00450                                           xmPushButtonWidgetClass,
00451                                           aux, NULL, 0);
00452 
00453        XtAddCallback(button_message, XmNarmCallback,
00454                     ButtonMessageCallback, NULL);
00455 
00456        button_quit = XtCreateManagedWidget("quit", xmPushButtonWidgetClass,
00457                                        aux, NULL, 0);
00458 
00459        XtAddCallback(button_quit, XmNarmCallback, ButtonQuitCallback, NULL);
00460 
00461        XtRealizeWidget(toplevel);
00462 
00463        aux_window = XtWindow(toplevel);
00464 
00465        if (None != XGetSelectionOwner(display, aux_ext_atom)) {
00466               fprintf(stderr, "%s\n", gettext("aux already exists"));
00467               exit(1);
00468        }
00469        XSetSelectionOwner(display, aux_ext_atom, aux_window, CurrentTime);
00470        if (aux_window != XGetSelectionOwner(display, aux_ext_atom)) {
00471               fprintf(stderr, "%s\n", gettext("aux seems existing"));
00472               exit(1);
00473        }
00474 
00475        XtAddEventHandler(toplevel, PropertyChangeMask, False, 
00476                        AuxEventHandler, NULL);
00477 
00478        XtAddEventHandler(toplevel, NoEventMask, True,
00479                        AuxEventHandler, NULL);
00480 
00481        ProcessInitialPropertyNotify();
00482 
00483        XtAppMainLoop(app);
00484 
00485        return 0;
00486 }