Jabber WindowGram Client (JWGC)

Introduction Screenshots Installation Downloads
Documentation Browse Source Resources Project Site

Stable Version
-none-

Latest Version
beta5



Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

xcut.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
00003  *      For copying and distribution information, see the file
00004  *      "mit-copyright.h".
00005  *
00006  *      Modified for jwgc by Daniel Henninger.
00007  */
00008 
00009 #include "mit-copyright.h"
00010 
00011 /****************************************************************************/
00012 /* */
00013 /* Code to deal with handling X events:                  */
00014 /* */
00015 /****************************************************************************/
00016 
00017 #ifndef X_DISPLAY_MISSING
00018 
00019 #include <X11/Xlib.h>
00020 #include <X11/Xutil.h>
00021 #include "new_string.h"
00022 #include "X_gram.h"
00023 #include "main.h"
00024 #include "xselect.h"
00025 #include "xmark.h"
00026 #include "error.h"
00027 #include "xrevstack.h"
00028 
00029 /*
00030  *
00031  */
00032 
00033 extern char *xmarkGetText();
00034 
00035 extern long ttl;
00036 
00037 static char *selected_text = NULL;
00038 static Window selecting_in = 0;
00039 
00040 char *
00041 getSelectedText()
00042 {
00043         return (selected_text);
00044 }
00045 
00046 /*
00047  *
00048  */
00049 
00050 /* ARGSUSED */
00051 Bool 
00052 isShiftButton1(dpy, event, arg)
00053         Display *dpy;
00054         XEvent *event;
00055         char *arg;
00056 {
00057         return (event->xbutton.state & (ShiftMask | Button1Mask));
00058 }
00059 
00060 /* ARGSUSED */
00061 Bool 
00062 isShiftButton3(dpy, event, arg)
00063         Display *dpy;
00064         XEvent *event;
00065         char *arg;
00066 {
00067         return (event->xbutton.state & (ShiftMask | Button3Mask));
00068 }
00069 
00070 void 
00071 getLastEvent(dpy, state, event)
00072         Display *dpy;
00073         unsigned int state;
00074         XEvent *event;
00075 {
00076         XEvent xev;
00077 
00078         if (state & Button1Mask) {
00079                 while (XCheckIfEvent(dpy, &xev, isShiftButton1, NULL))
00080                         *event = xev;
00081         }
00082         else if (state & Button3Mask) {
00083                 while (XCheckIfEvent(dpy, &xev, isShiftButton3, NULL))
00084                         *event = xev;
00085         }
00086 }
00087 
00088 void 
00089 xunmark(dpy, w, gram, desc_context)
00090         Display *dpy;
00091         Window w;
00092         x_gram *gram;
00093         XContext desc_context;
00094 {
00095         if (gram == NULL)
00096                 if (XFindContext(dpy, w, desc_context, (caddr_t *) & gram))
00097                         return;
00098 
00099         xmarkClear();
00100         xmarkRedraw(dpy, w, gram, XMARK_REDRAW_OLD);
00101 }
00102 
00103 /* This is out here so xdestroygram can get at it */
00104 
00105 #define PRESSOP_NONE 0          /* nothing */
00106 #define PRESSOP_KILL 1          /* normal click */
00107 #define PRESSOP_SEL  2          /* shift left */
00108 #define PRESSOP_EXT  3          /* shift right */
00109 #define PRESSOP_NUKE 4          /* ctrl */
00110 #define PRESSOP_STOP 5          /* pressop cancelled by moving out of window */
00111 
00112 static int current_pressop = PRESSOP_NONE;
00113 
00114 void 
00115 xdestroygram(dpy, w, desc_context, gram)
00116         Display *dpy;
00117         Window w;
00118         XContext desc_context;
00119         x_gram *gram;
00120 {
00121         struct timeval now;
00122 
00123         gettimeofday(&now, NULL);
00124         if ((gram->can_die.tv_sec == 0) ||
00125             (gram->can_die.tv_sec > now.tv_sec) ||
00126             ((gram->can_die.tv_sec == now.tv_sec) &&
00127              (gram->can_die.tv_usec > now.tv_usec)))
00128                 return;
00129 
00130         if (w == selecting_in) {
00131                 selecting_in = 0;
00132                 xmarkClear();
00133         }
00134         current_pressop = PRESSOP_NONE;
00135         XDeleteContext(dpy, w, desc_context);
00136         XDestroyWindow(dpy, w);
00137         delete_gram(gram);
00138         free(gram->text);
00139         free(gram->blocks);
00140         free(gram);
00141 
00142         if (bottom_gram == NULL && unlinked == NULL) {
00143                 /* flush colormap here */
00144         }
00145 }
00146 
00147 void 
00148 xcut(dpy, event, desc_context)
00149         Display *dpy;
00150         XEvent *event;
00151         XContext desc_context;
00152 {
00153         x_gram *gram;
00154         Window w = event->xany.window;
00155         int changedbound;
00156 
00157         /*
00158          * If event is for a window that's not ours anymore (say we're
00159          * in the process of deleting it...), ignore it:
00160          */
00161         if (XFindContext(dpy, w, desc_context, (caddr_t *) & gram))
00162                 return;
00163 
00164         /*
00165          * Dispatch on the event type:
00166          */
00167         switch (event->type) {
00168                 case ClientMessage:
00169                         if ((event->xclient.message_type == XA_WM_PROTOCOLS) &&
00170                             (event->xclient.format == 32) &&
00171                           (event->xclient.data.l[0] == XA_WM_DELETE_WINDOW))
00172                                 xdestroygram(dpy, w, desc_context, gram);
00173                         break;
00174 
00175                 case MapNotify:
00176                         /*
00177                          * I don't like using the local time, but MapNotify
00178                          * events don't come with a timestamp, and there's no
00179                          * way to query the server
00180                          */
00181 
00182                         if (gram->can_die.tv_sec == 0) {
00183                                 gettimeofday(&(gram->can_die), NULL);
00184                                 gram->can_die.tv_sec += (int) (ttl / 1000);
00185                                 gram->can_die.tv_usec += (ttl % 1000) * 1000;
00186                         }
00187                         break;
00188 
00189                 case UnmapNotify:
00190                         unlink_gram(gram);
00191                         break;
00192 
00193                 case LeaveNotify:
00194                         if (current_pressop == PRESSOP_KILL ||
00195                             current_pressop == PRESSOP_NUKE)
00196                                 current_pressop = PRESSOP_STOP;
00197                         break;
00198 
00199                 case MotionNotify:
00200                         if (current_pressop == PRESSOP_SEL) {
00201                                 /* getLastEvent(dpy,Button1Mask,event); */
00202                                 changedbound = xmarkExtendFromFirst(gram, event->xmotion.x,
00203                                                           event->xmotion.y);
00204                                 xmarkRedraw(dpy, w, gram, changedbound);
00205                         }
00206                         else if (current_pressop == PRESSOP_EXT) {
00207                                 /* getLastEvent(dpy,Button3Mask,event); */
00208                                 changedbound = xmarkExtendFromNearest(gram, event->xmotion.x,
00209                                                           event->xmotion.y);
00210                                 xmarkRedraw(dpy, w, gram, changedbound);
00211                         }
00212                         break;
00213 
00214                 case ButtonPress:
00215                         if (current_pressop != PRESSOP_NONE) {
00216                                 current_pressop = PRESSOP_STOP;
00217                         }
00218                         else if ((event->xbutton.state) & ShiftMask) {
00219                                 if (event->xbutton.button == Button1) {
00220                                         if (selecting_in)
00221                                                 xunmark(dpy, selecting_in, NULL, desc_context);
00222                                         if (selected_text)
00223                                                 free(selected_text);
00224                                         selected_text = NULL;
00225                                         if (!xselGetOwnership(dpy, w, event->xbutton.time)) {
00226                                                 XBell(dpy, 0);
00227                                                 ERROR("Unable to get ownership of PRIMARY selection.\n");
00228                                                 selecting_in = 0;
00229                                                 current_pressop = PRESSOP_STOP;
00230                                         }
00231                                         else {
00232                                                 selecting_in = w;
00233                                                 xmarkStart(gram, event->xbutton.x, event->xbutton.y);
00234                                                 current_pressop = PRESSOP_SEL;
00235                                         }
00236                                 }
00237                                 else if ((event->xbutton.button == Button3) &&
00238                                          (w == selecting_in)) {
00239                                         if (selected_text)
00240                                                 free(selected_text);
00241                                         selected_text = NULL;
00242                                         changedbound = xmarkExtendFromNearest(gram, event->xbutton.x,
00243                                                           event->xbutton.y);
00244                                         xmarkRedraw(dpy, w, gram, changedbound);
00245                                         selected_text = xmarkGetText();
00246                                         /*
00247                                          * this is ok, since to get here, the
00248                                          * selection must be owned
00249                                          */
00250                                         current_pressop = PRESSOP_EXT;
00251                                 }
00252                         }
00253                         else if ((event->xbutton.state) & ControlMask) {
00254                                 current_pressop = PRESSOP_NUKE;
00255                         }
00256                         else {
00257                                 current_pressop = PRESSOP_KILL;
00258                         }
00259                         break;
00260 
00261                 case ButtonRelease:
00262                         if (current_pressop == PRESSOP_KILL) {
00263                                 xdestroygram(dpy, w, desc_context, gram);
00264                         }
00265                         else if (current_pressop == PRESSOP_SEL ||
00266                                  current_pressop == PRESSOP_EXT) {
00267                                 if (selected_text)
00268                                         free(selected_text);
00269                                 selected_text = xmarkGetText();
00270                         }
00271                         else if (current_pressop == PRESSOP_NUKE) {
00272                                 XWindowAttributes wa;
00273                                 int gx, gy;
00274                                 Window temp;
00275                                 x_gram *next;
00276 
00277                                 for (gram = bottom_gram; gram; gram = next) {
00278                                         XGetWindowAttributes(dpy, gram->w, &wa);
00279                                         XTranslateCoordinates(dpy, gram->w, wa.root, 0, 0, &gx, &gy,
00280                                                               &temp);
00281 
00282                                         next = gram->above;
00283 
00284                                         if ((wa.map_state == IsViewable) &&
00285                                             (gx <= event->xbutton.x_root) &&
00286                                             (event->xbutton.x_root < gx + wa.width) &&
00287                                             (gy <= event->xbutton.y_root) &&
00288                                             (event->xbutton.y_root < gy + wa.height)) {
00289                                                 xdestroygram(dpy, gram->w, desc_context, gram);
00290                                         }
00291                                 }
00292                                 for (gram = unlinked; gram; gram = next) {
00293                                         XGetWindowAttributes(dpy, gram->w, &wa);
00294                                         XTranslateCoordinates(dpy, gram->w, wa.root, 0, 0, &gx, &gy,
00295                                                               &temp);
00296 
00297                                         next = gram->above;
00298 
00299                                         if ((wa.map_state == IsViewable) &&
00300                                             (gx <= event->xbutton.x_root) &&
00301                                             (event->xbutton.x_root < gx + wa.width) &&
00302                                             (gy <= event->xbutton.y_root) &&
00303                                             (event->xbutton.y_root < gy + wa.height)) {
00304                                                 xdestroygram(dpy, gram->w, desc_context, gram);
00305                                         }
00306                                 }
00307                         }
00308                         current_pressop = PRESSOP_NONE;
00309                         break;
00310 
00311                 case SelectionRequest:
00312                         xselProcessSelection(dpy, w, event);
00313                         break;
00314 
00315                 case SelectionClear:
00316                         xselOwnershipLost(event->xselectionclear.time);
00317                         if (w == selecting_in) {
00318                                 selecting_in = 0;
00319                                 xunmark(dpy, w, gram, desc_context);
00320                                 if (selected_text)
00321                                         free(selected_text);
00322                                 selected_text = NULL;
00323                         }
00324                         break;
00325 
00326                 default:
00327                         break;
00328         }
00329 
00330         XFlush(dpy);
00331 }
00332 
00333 #endif


Last updated at Tue Dec 18 21:07:42 PST 2007. This site and project hosted by...SourceForge.net Logo
Source Perspective by Fisheye