XCTRL_API void set_selection(Display*dpy, char kind, char *sel_buf, Bool utf8) { Atom seltype=selarg_to_seltype(dpy,kind); long sel_len=strlen(sel_buf); if (seltype == XA_STRING) { XStoreBuffer(dpy, (char*)sel_buf, (int)sel_len, 0); } else { XEvent evt; Window win = make_selection_window(dpy); Atom target = utf8 ? XA_UTF8_STRING(dpy) : XA_STRING; /* FIXME: Should not use CurrentTime per ICCCM section 2.1 */ XSetSelectionOwner(dpy, seltype, win, CurrentTime); while (1) { /* wait for a SelectionRequest event */ static uint clear = 0; static uint context = XCLIB_XCIN_NONE; static ulong sel_pos = 0; static Window cwin; static Atom pty; int finished; XNextEvent(dpy, &evt); finished = xcin(dpy, &cwin, evt, &pty, target, (uchar*)sel_buf, sel_len, &sel_pos, &context); if (evt.type == SelectionClear) { clear = 1; } if ((context == XCLIB_XCIN_NONE) && clear) { break; } if (finished) { break; } } XDestroyWindow(dpy,win); } }
int BC_Clipboard::to_clipboard(const char *data, long len, int clipboard_num) { //printf("BC_Clipboard::to_clipboard %d: %d '%*.*s'\n",clipboard_num,len,len,len,data); if(clipboard_num == BC_PRIMARY_SELECTION) { XStoreBuffer(out_display, data, len, clipboard_num); return 0; } #ifdef SINGLE_THREAD BC_Display::lock_display("BC_Clipboard::to_clipboard"); #else XLockDisplay(out_display); #endif // Store in local buffer if(this->data[clipboard_num] && length[clipboard_num] != len + 1) { delete [] this->data[clipboard_num]; this->data[clipboard_num] = 0; } if(!this->data[clipboard_num]) { length[clipboard_num] = len; this->data[clipboard_num] = new char[len + 1]; memcpy(this->data[clipboard_num], data, len); this->data[clipboard_num][len] = 0; } if(clipboard_num == PRIMARY_SELECTION) { XSetSelectionOwner(out_display, primary, out_win, CurrentTime); } else if(clipboard_num == SECONDARY_SELECTION) { XSetSelectionOwner(out_display, secondary, out_win, CurrentTime); } XFlush(out_display); #ifdef SINGLE_THREAD BC_Display::unlock_display(); #else XUnlockDisplay(out_display); #endif return 0; }
static int SetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Tk_Window tkwin = clientData; int buffer; char *string; int length; buffer = 0; if (objc == 4) { if (GetCutNumberFromObj(interp, objv[3], &buffer) != TCL_OK) { return TCL_ERROR; } } string = Tcl_GetStringFromObj(objv[2], &length); XStoreBuffer(Tk_Display(tkwin), string, length + 1, buffer); return TCL_OK; }
static void StoreBuffer(Widget w, XtPointer client_data, Atom *selection, Atom *type, XtPointer value, unsigned long *length, int *format) { if (*type == 0 || *type == XT_CONVERT_FAIL || *length == 0) { #ifdef XKB XkbStdBell( XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError ); #else XBell( XtDisplay(w), 0 ); #endif return; } XStoreBuffer( XtDisplay(w), (char*)value, (int)(*length), options.buffer ); XtFree(value); }
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton) { unsigned int modif; int x1,x2,y1,y2,i; Window Win1,Win2; int PosCurs=0; int SizeBuf; char *str; int NewPos; Atom type; XEvent event; int ButPress=1; int format; unsigned long longueur,octets_restant; unsigned char *donnees=(unsigned char *)""; XRectangle rect; /* On deplace le curseur a la position de la souris */ /* On recupere la position de la souris */ /* We move the cursor at mouse position and we get the mouse position */ switch (EvtButton->button) { case Button1: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title+xobj->value3))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=PosCurs+xobj->value3; xobj->value2=PosCurs+xobj->value3; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj); while (ButPress) { XNextEvent(dpy, &event); switch (event.type) { case MotionNotify: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title+xobj->value3))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; /* Limitation de la zone de dessin */ /* limitation of the drawing zone */ if (PosCurs>xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2); rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } else if (PosCurs<xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1; rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3, xobj->value2+1) - rect.x+2; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } break; case ButtonRelease: ButPress=0; break; } } /* Enregistrement de la selection dans le presse papier */ /* Le programme devient proprietaire de la selection */ /* selection stuff: get the selection */ if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time); SelectOneTextField(xobj); } break; case Button2: /* Colle le texte */ /* Si l'application possede pas la selection, elle la demande */ /* sinon elle lit son presse papier */ /* read the selection */ if (!x11base->HaveXSelection) { /* Demande de la selection */ /* ask for the selection */ XConvertSelection(dpy,XA_PRIMARY,XA_STRING,propriete,*xobj->ParentWin, EvtButton->time); while (!(XCheckTypedEvent(dpy,SelectionNotify,&event))) ; if (event.xselection.property!=None) if (event.xselection.selection==XA_PRIMARY) { XGetWindowProperty(dpy,event.xselection.requestor, event.xselection.property,0,8192,False, event.xselection.target,&type,&format, &longueur,&octets_restant,&donnees); if (longueur>0) { Scrapt=(char*)realloc((void*)Scrapt,(longueur+1)*sizeof(char)); Scrapt=strcpy(Scrapt,(char *)donnees); XDeleteProperty(dpy,event.xselection.requestor, event.xselection.property); XFree(donnees); } } } SizeBuf=strlen(Scrapt); if (SizeBuf>0) { NewPos=InsertText(xobj,Scrapt,SizeBuf); DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=NewPos; xobj->value2=NewPos; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj); SendMsg(xobj,SingleClic); } break; case Button3: /* Appuie sur le troisieme bouton */ XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; if ((PosCurs<xobj->value) && (xobj->value<xobj->value2)) xobj->value=xobj->value2; if ((PosCurs>xobj->value) && (xobj->value>xobj->value2)) xobj->value=xobj->value2; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); while (ButPress) { XNextEvent(dpy, &event); switch (event.type) { case MotionNotify: XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif); x2=x2-xobj->x; while ((PosCurs<strlen(xobj->title))&& (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8)) PosCurs++; if (PosCurs>xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2); rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs; DrawTextField(xobj); } else if (PosCurs<xobj->value2) { rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1; rect.y=0; rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3, xobj->value2+1)-rect.x+2; rect.height=xobj->height; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj); } PosCurs=0; break; case ButtonRelease: ButPress=0; break; } } if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time); } break; } }
int main(int argc, char **argv) { Display *dpy; int i; int buffer = -1; char *filename = NULL; FILE *file = stdin; char *buf = NULL; char *display_name = ""; int l = 0; int buf_len = 0; int limit_check = 1; int clear_selection = 0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { print_help(); exit(0); } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) { printf("%s (Window Maker %s)\n", __progname, VERSION); exit(0); } else if (strcmp(argv[i], "-cutbuffer") == 0 || strcmp(argv[i], "--cutbuffer") == 0) { if (i < argc - 1) { i++; if (sscanf(argv[i], "%i", &buffer) != 1) { fprintf(stderr, "%s: could not convert '%s' to int\n", __progname, argv[i]); exit(1); } if (buffer < 0 || buffer > 7) { fprintf(stderr, "%s: invalid buffer number %i\n", __progname, buffer); exit(1); } } else { printf("%s: missing argument for '%s'\n", __progname, argv[i]); printf("Try '%s --help' for more information\n", __progname); exit(1); } } else if (strcmp(argv[i], "-display") == 0) { if (i < argc - 1) { display_name = argv[++i]; } else { printf("%s: missing argument for '%s'\n", __progname, argv[i]); printf("Try '%s --help' for more information\n", __progname); exit(1); } } else if (strcmp(argv[i], "-clearselection") == 0 || strcmp(argv[i], "--clear-selection") == 0) { clear_selection = 1; } else if (strcmp(argv[i], "-nolimit") == 0 || strcmp(argv[i], "--no-limit") == 0) { limit_check = 0; } else { printf("%s: invalid argument '%s'\n", __progname, argv[i]); printf("Try '%s --help' for more information\n", __progname); exit(1); } } else { filename = argv[i]; } } if (filename) { file = fopen(filename, "rb"); if (!file) { char line[1024]; sprintf(line, "%s: could not open \"%s\"", __progname, filename); perror(line); exit(1); } } dpy = XOpenDisplay(display_name); XSetErrorHandler(errorHandler); if (!dpy) { fprintf(stderr, "%s: could not open display \"%s\"\n", __progname, XDisplayName(display_name)); exit(1); } if (buffer < 0) { Atom *rootWinProps; int exists[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int i, count; /* Create missing CUT_BUFFERs */ rootWinProps = XListProperties(dpy, DefaultRootWindow(dpy), &count); for (i = 0; i < count; i++) { switch (rootWinProps[i]) { case XA_CUT_BUFFER0: exists[0] = 1; break; case XA_CUT_BUFFER1: exists[1] = 1; break; case XA_CUT_BUFFER2: exists[2] = 1; break; case XA_CUT_BUFFER3: exists[3] = 1; break; case XA_CUT_BUFFER4: exists[4] = 1; break; case XA_CUT_BUFFER5: exists[5] = 1; break; case XA_CUT_BUFFER6: exists[6] = 1; break; case XA_CUT_BUFFER7: exists[7] = 1; break; default: break; } } if (rootWinProps) { XFree(rootWinProps); } for (i = 0; i < 8; i++) { if (!exists[i]) { XStoreBuffer(dpy, "", 0, i); } } XRotateBuffers(dpy, 1); buffer = 0; } while (!feof(file)) { char *nbuf; char tmp[LINESIZE + 2]; int nl = 0; /* * Use read() instead of fgets() to preserve NULLs, since * especially since there's no reason to read one line at a time. */ if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) { break; } if (buf_len == 0) { nbuf = malloc(buf_len = l + nl + 1); } else if (buf_len < l + nl + 1) { /* * To avoid terrible performance on big input buffers, * grow by doubling, not by the minimum needed for the * current line. */ buf_len = 2 * buf_len + nl + 1; /* some realloc implementations don't do malloc if buf==NULL */ if (buf == NULL) { nbuf = malloc(buf_len); } else { nbuf = realloc(buf, buf_len); } } else { nbuf = buf; } if (!nbuf) { fprintf(stderr, "%s: out of memory\n", __progname); exit(1); } buf = nbuf; /* * Don't strcat, since it would make the algorithm n-squared. * Don't use strcpy, since it stops on a NUL. */ memcpy(buf + l, tmp, nl); l += nl; if (limit_check && l >= MAXDATA) { fprintf (stderr, "%s: too much data in input - more than %d bytes\n" " use the -nolimit argument to remove the limit check.\n", __progname, MAXDATA); exit(1); } } if (clear_selection) { XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime); } if (buf) { XStoreBuffer(dpy, buf, l, buffer); } XFlush(dpy); XCloseDisplay(dpy); exit(buf == NULL || errno != 0); }
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton) { unsigned int modif; int x1,x2,y1,y2,i; Window Win1,Win2; int PosCurs=0; int SizeBuf; char *str; int NewPos; Atom type; XEvent event; int ButPress=1; int format; unsigned long longueur,octets_restant; unsigned char *donnees=(unsigned char *)""; XRectangle rect; int start_pos, selection_pos, curs_pos; /* On deplace le curseur a la position de la souris */ /* On recupere la position de la souris */ /* We move the cursor at mouse position and we get the mouse position */ switch (EvtButton->button) { case Button1: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2, &modif); x2=x2-xobj->x; /* see where we clicked */ PosCurs=0; /* byte position of first visible character */ start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); /* cursor offset in bytes */ curs_pos = 0; while ((curs_pos < strlen(xobj->title + start_pos)) && (x2 > FlocaleTextWidth( xobj->Ffont,xobj->title + start_pos, curs_pos) + 8)) { curs_pos += FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + start_pos + curs_pos); PosCurs++; } DrawPointTxt(xobj,xobj->TabColor[back]); /* set selection start and end where clicked */ /* first visible char + position clicked */ xobj->value = PosCurs + xobj->value3; xobj->value2 = PosCurs + xobj->value3; /* byte offset corresponding to the above */ start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); selection_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title, xobj->value3); DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj,NULL); while (ButPress) { FNextEvent(dpy, &event); switch (event.type) { case MotionNotify: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1, &y1,&x2,&y2,&modif); x2=x2-xobj->x; PosCurs=0; curs_pos = 0; /* determine how far in the mouse is now */ while ((curs_pos < strlen( xobj->title + start_pos)) && (x2 > FlocaleTextWidth( xobj->Ffont,xobj->title+ start_pos, curs_pos) + 8)) { curs_pos += FlocaleStringNumberOfBytes( xobj->Ffont, xobj->title + start_pos + curs_pos); PosCurs++; } /* Limitation de la zone de dessin */ /* limitation of the drawing zone */ /* these 2 if-statements updates current cursor position of the widget if needed */ if (PosCurs > (xobj->value2 - xobj->value3)) { /* select made "forward" */ rect.x= FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, selection_pos - start_pos); rect.y=0; rect.width= FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, curs_pos) -rect.x+1; rect.height=xobj->height; xobj->value2 = PosCurs + xobj->value3; DrawTextField(xobj,NULL); } else if (PosCurs < (xobj->value2 - xobj->value3)) { /* selection made "backwards" */ rect.x=FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, curs_pos) - 1; rect.y=0; rect.width=FlocaleTextWidth( xobj->Ffont, xobj->title+ start_pos, selection_pos - start_pos) - rect.x+2; rect.height=xobj->height; xobj->value2= PosCurs + xobj->value3; DrawTextField(xobj,NULL); } break; case ButtonRelease: ButPress=0; break; } } /* Enregistrement de la selection dans le presse papier */ /* Le programme devient proprietaire de la selection */ /* selection stuff: get the selection */ if (xobj->value != xobj->value2) { str=(char*)GetText(xobj, xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt = (char*)realloc( (void*)Scrapt, (strlen(str)+2)*sizeof(char)); Scrapt = strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner( dpy,XA_PRIMARY,x11base->win,EvtButton->time); SelectOneTextField(xobj); } break; case Button2: /* Colle le texte */ /* Si l'application possede pas la selection, elle la demande */ /* sinon elle lit son presse papier */ /* read the selection */ if (!x11base->HaveXSelection) { /* Demande de la selection */ /* ask for the selection */ XConvertSelection( dpy,XA_PRIMARY,XA_STRING,propriete, *xobj->ParentWin, EvtButton->time); while (!(FCheckTypedEvent(dpy,SelectionNotify,&event))) ; if (event.xselection.property!=None) if (event.xselection.selection==XA_PRIMARY) { XGetWindowProperty( dpy,event.xselection.requestor, event.xselection.property,0L, 8192L,False, event.xselection.target,&type, &format, &longueur, &octets_restant,&donnees); if (longueur>0) { Scrapt=(char*)realloc( (void*)Scrapt, (longueur+1)* sizeof(char)); Scrapt=strcpy( Scrapt,(char *)donnees); XDeleteProperty( dpy, event.xselection. requestor, event.xselection. property); XFree(donnees); } } } SizeBuf=strlen(Scrapt); if (SizeBuf>0) { NewPos=InsertText(xobj,Scrapt,SizeBuf); DrawPointTxt(xobj,xobj->TabColor[back]); xobj->value=NewPos; xobj->value2=NewPos; DrawPointTxt(xobj,xobj->TabColor[fore]); DrawTextField(xobj,NULL); SendMsg(xobj,SingleClic); } break; case Button3: /* Appuie sur le troisieme bouton */ FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2, &modif); x2=x2-xobj->x; PosCurs=0; while ((PosCurs<strlen(xobj->title))&& (x2>FlocaleTextWidth( xobj->Ffont,xobj->title+xobj->value3, PosCurs)+8)) PosCurs++; if ((PosCurs<xobj->value) && (xobj->value<xobj->value2)) xobj->value=xobj->value2; if ((PosCurs>xobj->value) && (xobj->value>xobj->value2)) xobj->value=xobj->value2; xobj->value2=PosCurs+xobj->value3; DrawTextField(xobj,NULL); while (ButPress) { FNextEvent(dpy, &event); switch (event.type) { case MotionNotify: FQueryPointer( dpy,*xobj->ParentWin,&Win1,&Win2,&x1, &y1,&x2,&y2,&modif); x2=x2-xobj->x; while ((PosCurs<strlen(xobj->title))&& (x2 > FlocaleTextWidth( xobj->Ffont, xobj->title+xobj->value3, PosCurs)+8)) PosCurs++; if (PosCurs>xobj->value2) { rect.x= FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3, xobj->value2); rect.y=0; rect.width= FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3,PosCurs+1) -rect.x+1; rect.height=xobj->height; xobj->value2=PosCurs; DrawTextField(xobj,NULL); } else if (PosCurs<xobj->value2) { rect.x=FlocaleTextWidth( xobj->Ffont, xobj->title+ xobj->value3, PosCurs)-1; rect.y=0; rect.width=FlocaleTextWidth( xobj->Ffont, xobj->title+xobj-> value3, xobj->value2+1)- rect.x+2; rect.height=xobj->height; xobj->value2= PosCurs+xobj->value3; DrawTextField(xobj,NULL); } PosCurs=0; break; case ButtonRelease: ButPress=0; break; } } if (xobj->value!=xobj->value2) { str=(char*)GetText(xobj,xobj->value2); for (i=0;i<=7;i++) XStoreBuffer(dpy,str,strlen(str),i); Scrapt=(char*)realloc( (void*)Scrapt,(strlen(str)+2)*sizeof(char)); Scrapt=strcpy(Scrapt,str); free(str); x11base->HaveXSelection=True; XSetSelectionOwner( dpy,XA_PRIMARY,x11base->win,EvtButton->time); } break; } }
WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * context) { W_Screen *scrPtr; XGCValues gcv; Pixmap stipple; static int initialized = 0; static char *atomNames[] = { "_GNUSTEP_WM_ATTR", "WM_DELETE_WINDOW", "WM_PROTOCOLS", "CLIPBOARD", "XdndAware", "XdndSelection", "XdndEnter", "XdndLeave", "XdndPosition", "XdndDrop", "XdndFinished", "XdndTypeList", "XdndActionList", "XdndActionDescription", "XdndStatus", "XdndActionCopy", "XdndActionMove", "XdndActionLink", "XdndActionAsk", "XdndActionPrivate", "_WINGS_DND_MOUSE_OFFSET", "WM_STATE", "UTF8_STRING", "_NET_WM_NAME", "_NET_WM_ICON_NAME", "_NET_WM_ICON", }; Atom atoms[wlengthof(atomNames)]; int i; if (!initialized) { initialized = 1; W_ReadConfigurations(); assert(W_ApplicationInitialized()); } scrPtr = malloc(sizeof(W_Screen)); if (!scrPtr) return NULL; memset(scrPtr, 0, sizeof(W_Screen)); scrPtr->aflags.hasAppIcon = 1; scrPtr->display = display; scrPtr->screen = screen; scrPtr->rcontext = context; scrPtr->depth = context->depth; scrPtr->visual = context->visual; scrPtr->lastEventTime = 0; scrPtr->colormap = context->cmap; scrPtr->rootWin = RootWindow(display, screen); scrPtr->fontCache = WMCreateHashTable(WMStringPointerHashCallbacks); scrPtr->xftdraw = XftDrawCreate(scrPtr->display, W_DRAWABLE(scrPtr), scrPtr->visual, scrPtr->colormap); /* Create missing CUT_BUFFERs */ { Atom *rootWinProps; int exists[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int count; rootWinProps = XListProperties(display, scrPtr->rootWin, &count); for (i = 0; i < count; i++) { switch (rootWinProps[i]) { case XA_CUT_BUFFER0: exists[0] = 1; break; case XA_CUT_BUFFER1: exists[1] = 1; break; case XA_CUT_BUFFER2: exists[2] = 1; break; case XA_CUT_BUFFER3: exists[3] = 1; break; case XA_CUT_BUFFER4: exists[4] = 1; break; case XA_CUT_BUFFER5: exists[5] = 1; break; case XA_CUT_BUFFER6: exists[6] = 1; break; case XA_CUT_BUFFER7: exists[7] = 1; break; default: break; } } if (rootWinProps) { XFree(rootWinProps); } for (i = 0; i < 8; i++) { if (!exists[i]) { XStoreBuffer(display, "", 0, i); } } } scrPtr->ignoredModifierMask = 0; { int i; XModifierKeymap *modmap; KeyCode nlock, slock; static int mask_table[8] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; unsigned int numLockMask = 0, scrollLockMask = 0; nlock = XKeysymToKeycode(display, XK_Num_Lock); slock = XKeysymToKeycode(display, XK_Scroll_Lock); /* * Find out the masks for the NumLock and ScrollLock modifiers, * so that we can bind the grabs for when they are enabled too. */ modmap = XGetModifierMapping(display); if (modmap != NULL && modmap->max_keypermod > 0) { for (i = 0; i < 8 * modmap->max_keypermod; i++) { if (modmap->modifiermap[i] == nlock && nlock != 0) numLockMask = mask_table[i / modmap->max_keypermod]; else if (modmap->modifiermap[i] == slock && slock != 0) scrollLockMask = mask_table[i / modmap->max_keypermod]; } } if (modmap) XFreeModifiermap(modmap); scrPtr->ignoredModifierMask = numLockMask | scrollLockMask | LockMask; } /* initially allocate some colors */ WMWhiteColor(scrPtr); WMBlackColor(scrPtr); WMGrayColor(scrPtr); WMDarkGrayColor(scrPtr); gcv.graphics_exposures = False; gcv.function = GXxor; gcv.foreground = W_PIXEL(scrPtr->white); if (gcv.foreground == 0) gcv.foreground = 1; scrPtr->xorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures | GCForeground, &gcv); gcv.function = GXxor; gcv.foreground = W_PIXEL(scrPtr->gray); gcv.subwindow_mode = IncludeInferiors; scrPtr->ixorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures | GCForeground | GCSubwindowMode, &gcv); gcv.function = GXcopy; scrPtr->copyGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures, &gcv); scrPtr->clipGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures, &gcv); stipple = XCreateBitmapFromData(display, W_DRAWABLE(scrPtr), STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT); gcv.foreground = W_PIXEL(scrPtr->darkGray); gcv.background = W_PIXEL(scrPtr->gray); gcv.fill_style = FillStippled; gcv.stipple = stipple; scrPtr->stippleGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCForeground | GCBackground | GCStipple | GCFillStyle | GCGraphicsExposures, &gcv); scrPtr->drawStringGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCGraphicsExposures, &gcv); scrPtr->drawImStringGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCGraphicsExposures, &gcv); /* we need a 1bpp drawable for the monoGC, so borrow this one */ scrPtr->monoGC = XCreateGC(display, stipple, 0, NULL); scrPtr->stipple = stipple; scrPtr->antialiasedText = WINGsConfiguration.antialiasedText; scrPtr->normalFont = WMSystemFontOfSize(scrPtr, 0); scrPtr->boldFont = WMBoldSystemFontOfSize(scrPtr, 0); if (!scrPtr->boldFont) scrPtr->boldFont = scrPtr->normalFont; if (!scrPtr->normalFont) { wwarning(_("could not load any fonts. Make sure your font installation" " and locale settings are correct.")); return NULL; } /* create input method stuff */ W_InitIM(scrPtr); scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON, CHECK_BUTTON_ON_WIDTH, CHECK_BUTTON_ON_HEIGHT, False); scrPtr->checkButtonImageOff = makePixmap(scrPtr, CHECK_BUTTON_OFF, CHECK_BUTTON_OFF_WIDTH, CHECK_BUTTON_OFF_HEIGHT, False); scrPtr->radioButtonImageOn = makePixmap(scrPtr, RADIO_BUTTON_ON, RADIO_BUTTON_ON_WIDTH, RADIO_BUTTON_ON_HEIGHT, False); scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF, RADIO_BUTTON_OFF_WIDTH, RADIO_BUTTON_OFF_HEIGHT, False); scrPtr->tristateButtonImageOn = makePixmap(scrPtr, TRISTATE_BUTTON_ON, TRISTATE_BUTTON_ON_WIDTH, TRISTATE_BUTTON_ON_HEIGHT, False); scrPtr->tristateButtonImageOff = makePixmap(scrPtr, TRISTATE_BUTTON_OFF, TRISTATE_BUTTON_OFF_WIDTH, TRISTATE_BUTTON_OFF_HEIGHT, False); scrPtr->tristateButtonImageTri = makePixmap(scrPtr, TRISTATE_BUTTON_TRI, TRISTATE_BUTTON_TRI_WIDTH, TRISTATE_BUTTON_TRI_HEIGHT, False); scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, False); scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2, BUTTON_ARROW2_WIDTH, BUTTON_ARROW2_HEIGHT, False); scrPtr->scrollerDimple = makePixmap(scrPtr, SCROLLER_DIMPLE, SCROLLER_DIMPLE_WIDTH, SCROLLER_DIMPLE_HEIGHT, False); scrPtr->upArrow = makePixmap(scrPtr, SCROLLER_ARROW_UP, SCROLLER_ARROW_UP_WIDTH, SCROLLER_ARROW_UP_HEIGHT, True); scrPtr->downArrow = makePixmap(scrPtr, SCROLLER_ARROW_DOWN, SCROLLER_ARROW_DOWN_WIDTH, SCROLLER_ARROW_DOWN_HEIGHT, True); scrPtr->leftArrow = makePixmap(scrPtr, SCROLLER_ARROW_LEFT, SCROLLER_ARROW_LEFT_WIDTH, SCROLLER_ARROW_LEFT_HEIGHT, True); scrPtr->rightArrow = makePixmap(scrPtr, SCROLLER_ARROW_RIGHT, SCROLLER_ARROW_RIGHT_WIDTH, SCROLLER_ARROW_RIGHT_HEIGHT, True); scrPtr->hiUpArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_UP, SCROLLER_ARROW_UP_WIDTH, SCROLLER_ARROW_UP_HEIGHT, True); scrPtr->hiDownArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_DOWN, SCROLLER_ARROW_DOWN_WIDTH, SCROLLER_ARROW_DOWN_HEIGHT, True); scrPtr->hiLeftArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_LEFT, SCROLLER_ARROW_LEFT_WIDTH, SCROLLER_ARROW_LEFT_HEIGHT, True); scrPtr->hiRightArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_RIGHT, SCROLLER_ARROW_RIGHT_WIDTH, SCROLLER_ARROW_RIGHT_HEIGHT, True); scrPtr->popUpIndicator = makePixmap(scrPtr, POPUP_INDICATOR, POPUP_INDICATOR_WIDTH, POPUP_INDICATOR_HEIGHT, True); scrPtr->pullDownIndicator = makePixmap(scrPtr, PULLDOWN_INDICATOR, PULLDOWN_INDICATOR_WIDTH, PULLDOWN_INDICATOR_HEIGHT, True); scrPtr->checkMark = makePixmap(scrPtr, CHECK_MARK, CHECK_MARK_WIDTH, CHECK_MARK_HEIGHT, True); loadPixmaps(scrPtr); scrPtr->defaultCursor = XCreateFontCursor(display, XC_left_ptr); scrPtr->textCursor = XCreateFontCursor(display, XC_xterm); { XColor bla; Pixmap blank; blank = XCreatePixmap(display, scrPtr->stipple, 1, 1, 1); XSetForeground(display, scrPtr->monoGC, 0); XFillRectangle(display, blank, scrPtr->monoGC, 0, 0, 1, 1); scrPtr->invisibleCursor = XCreatePixmapCursor(display, blank, blank, &bla, &bla, 0, 0); XFreePixmap(display, blank); } #ifdef HAVE_XINTERNATOMS XInternAtoms(display, atomNames, wlengthof(atomNames), False, atoms); #else for (i = 0; i < wlengthof(atomNames); i++) { atoms[i] = XInternAtom(display, atomNames[i], False); } #endif i = 0; scrPtr->attribsAtom = atoms[i++]; scrPtr->deleteWindowAtom = atoms[i++]; scrPtr->protocolsAtom = atoms[i++]; scrPtr->clipboardAtom = atoms[i++]; scrPtr->xdndAwareAtom = atoms[i++]; scrPtr->xdndSelectionAtom = atoms[i++]; scrPtr->xdndEnterAtom = atoms[i++]; scrPtr->xdndLeaveAtom = atoms[i++]; scrPtr->xdndPositionAtom = atoms[i++]; scrPtr->xdndDropAtom = atoms[i++]; scrPtr->xdndFinishedAtom = atoms[i++]; scrPtr->xdndTypeListAtom = atoms[i++]; scrPtr->xdndActionListAtom = atoms[i++]; scrPtr->xdndActionDescriptionAtom = atoms[i++]; scrPtr->xdndStatusAtom = atoms[i++]; scrPtr->xdndActionCopy = atoms[i++]; scrPtr->xdndActionMove = atoms[i++]; scrPtr->xdndActionLink = atoms[i++]; scrPtr->xdndActionAsk = atoms[i++]; scrPtr->xdndActionPrivate = atoms[i++]; scrPtr->wmIconDragOffsetAtom = atoms[i++]; scrPtr->wmStateAtom = atoms[i++]; scrPtr->utf8String = atoms[i++]; scrPtr->netwmName = atoms[i++]; scrPtr->netwmIconName = atoms[i++]; scrPtr->netwmIcon = atoms[i++]; scrPtr->rootView = W_CreateRootView(scrPtr); scrPtr->balloon = W_CreateBalloon(scrPtr); W_InitApplication(scrPtr); return scrPtr; }
static void handleTextFieldActionEvents(XEvent * event, void *data) { TextField *tPtr = (TextField *) data; static Time lastButtonReleasedEvent = 0; static Time lastButtonReleasedEvent2 = 0; Display *dpy = event->xany.display; CHECK_CLASS(data, WC_TextField); switch (event->type) { case KeyPress: if (tPtr->flags.waitingSelection) { return; } if (tPtr->flags.enabled && tPtr->flags.focused) { handleTextFieldKeyPress(tPtr, event); XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->invisibleCursor); tPtr->flags.pointerGrabbed = 1; } break; case MotionNotify: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); } if (tPtr->flags.waitingSelection) { return; } if (tPtr->flags.enabled && (event->xmotion.state & Button1Mask)) { if (tPtr->viewPosition < tPtr->textLen && event->xmotion.x > tPtr->usableWidth) { if (WMWidthOfString(tPtr->font, &(tPtr->text[tPtr->viewPosition]), tPtr->cursorPosition - tPtr->viewPosition) > tPtr->usableWidth) { tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition], tPtr->textLen - tPtr->viewPosition); } } else if (tPtr->viewPosition > 0 && event->xmotion.x < 0) { paintCursor(tPtr); tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition], tPtr->viewPosition); } tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xmotion.x); /* Do not allow text selection in secure textfields */ if (tPtr->flags.secure) { tPtr->selection.position = tPtr->cursorPosition; } tPtr->selection.count = tPtr->cursorPosition - tPtr->selection.position; paintCursor(tPtr); paintTextField(tPtr); } break; case ButtonPress: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); break; } if (tPtr->flags.waitingSelection) { break; } switch (tPtr->flags.alignment) { int textWidth; case WARight: textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen); if (tPtr->flags.enabled && !tPtr->flags.focused) { WMSetFocusToWidget(tPtr); } if (tPtr->flags.focused) { tPtr->selection.position = tPtr->cursorPosition; tPtr->selection.count = 0; } if (textWidth < tPtr->usableWidth) { tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x - tPtr->usableWidth + textWidth); } else tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x); paintTextField(tPtr); break; case WALeft: if (tPtr->flags.enabled && !tPtr->flags.focused) { WMSetFocusToWidget(tPtr); } if (tPtr->flags.focused && event->xbutton.button == Button1) { tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x); tPtr->selection.position = tPtr->cursorPosition; tPtr->selection.count = 0; paintTextField(tPtr); } if (event->xbutton.button == Button2 && tPtr->flags.enabled) { char *text; int n; if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, event->xbutton.time, pasteText, NULL)) { text = XFetchBuffer(tPtr->view->screen->display, &n, 0); if (text) { text[n] = 0; WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition); XFree(text); NOTIFY(tPtr, didChange, WMTextDidChangeNotification, (void *)WMInsertTextEvent); } } else { tPtr->flags.waitingSelection = 1; } } break; default: break; } break; case ButtonRelease: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = 0; XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor); } if (tPtr->flags.waitingSelection) { break; } if (!tPtr->flags.secure && tPtr->selection.count != 0) { int start, count; XRotateBuffers(dpy, 1); count = abs(tPtr->selection.count); if (tPtr->selection.count < 0) start = tPtr->selection.position - count; else start = tPtr->selection.position; XStoreBuffer(dpy, &tPtr->text[start], count, 0); } if (!tPtr->flags.secure && event->xbutton.time - lastButtonReleasedEvent <= WINGsConfiguration.doubleClickDelay) { if (event->xbutton.time - lastButtonReleasedEvent2 <= 2 * WINGsConfiguration.doubleClickDelay) { tPtr->selection.position = 0; tPtr->selection.count = tPtr->textLen; } else { int pos, cnt; char *txt; pos = tPtr->selection.position; cnt = tPtr->selection.count; txt = tPtr->text; while (pos >= 0) { if (txt[pos] == ' ' || txt[pos] == '\t') break; pos--; } pos++; while (pos + cnt < tPtr->textLen) { if (txt[pos + cnt] == ' ' || txt[pos + cnt] == '\t') break; cnt++; } tPtr->selection.position = pos; tPtr->selection.count = cnt; } paintTextField(tPtr); if (!tPtr->flags.ownsSelection) { tPtr->flags.ownsSelection = WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL); } } else if (!tPtr->flags.secure && tPtr->selection.count != 0 && !tPtr->flags.ownsSelection) { tPtr->flags.ownsSelection = WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL); } lastButtonReleasedEvent2 = lastButtonReleasedEvent; lastButtonReleasedEvent = event->xbutton.time; break; } }
static int doIn(Window win, const char *progname) { unsigned char *sel_buf; /* buffer for selection data */ unsigned long sel_len = 0; /* length of sel_buf */ unsigned long sel_all = 0; /* allocated size of sel_buf */ XEvent evt; /* X Event Structures */ int dloop = 0; /* done loops counter */ /* in mode */ sel_all = 16; /* Reasonable ballpark figure */ sel_buf = xcmalloc(sel_all * sizeof(char)); /* Put chars into inc from stdin or files until we hit EOF */ do { if (fil_number == 0) { /* read from stdin if no files specified */ fil_handle = stdin; } else { if ((fil_handle = fopen(fil_names[fil_current], "r")) == NULL) { errperror(3, progname, ": ", fil_names[fil_current] ); return EXIT_FAILURE; } else { /* file opened successfully. Print * message (verbose mode only). */ if (fverb == OVERBOSE) fprintf(stderr, "Reading %s...\n", fil_names[fil_current] ); } } fil_current++; while (!feof(fil_handle)) { /* If sel_buf is full (used elems = * allocated elems) */ if (sel_len == sel_all) { /* double the number of * allocated elements */ sel_all *= 2; sel_buf = (unsigned char *) xcrealloc(sel_buf, sel_all * sizeof(char) ); } sel_len += fread(sel_buf + sel_len, sizeof(char), sel_all - sel_len, fil_handle); } } while (fil_current < fil_number); /* if there are no files being read from (i.e., input * is from stdin not files, and we are in filter mode, * spit all the input back out to stdout */ if ((fil_number == 0) && ffilt) { fwrite(sel_buf, sizeof(char), sel_len, stdout); fclose(stdout); } /* Handle cut buffer if needed */ if (sseln == XA_STRING) { XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, 0); return EXIT_SUCCESS; } /* take control of the selection so that we receive * SelectionRequest events from other windows */ /* FIXME: Should not use CurrentTime, according to ICCCM section 2.1 */ XSetSelectionOwner(dpy, sseln, win, CurrentTime); /* fork into the background, exit parent process if we * are in silent mode */ if (fverb == OSILENT) { pid_t pid; pid = fork(); /* exit the parent process; */ if (pid) exit(EXIT_SUCCESS); } /* print a message saying what we're waiting for */ if (fverb > OSILENT) { if (sloop == 1) fprintf(stderr, "Waiting for one selection request.\n"); if (sloop < 1) fprintf(stderr, "Waiting for selection requests, Control-C to quit\n"); if (sloop > 1) fprintf(stderr, "Waiting for %i selection requests, Control-C to quit\n", sloop); } /* Avoid making the current directory in use, in case it will need to be umounted */ chdir("/"); /* loop and wait for the expected number of * SelectionRequest events */ while (dloop < sloop || sloop < 1) { /* print messages about what we're waiting for * if not in silent mode */ if (fverb > OSILENT) { if (sloop > 1) fprintf(stderr, " Waiting for selection request %i of %i.\n", dloop + 1, sloop); if (sloop == 1) fprintf(stderr, " Waiting for a selection request.\n"); if (sloop < 1) fprintf(stderr, " Waiting for selection request number %i\n", dloop + 1); } /* wait for a SelectionRequest event */ while (1) { static unsigned int clear = 0; static unsigned int context = XCLIB_XCIN_NONE; static unsigned long sel_pos = 0; static Window cwin; static Atom pty; int finished; XNextEvent(dpy, &evt); finished = xcin(dpy, &cwin, evt, &pty, target, sel_buf, sel_len, &sel_pos, &context); if (evt.type == SelectionClear) clear = 1; if ((context == XCLIB_XCIN_NONE) && clear) return EXIT_SUCCESS; if (finished) break; } dloop++; /* increment loop counter */ } return EXIT_SUCCESS; }