ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvttoolkit.C
(Generate patch)

Comparing rxvt-unicode/src/rxvttoolkit.C (file contents):
Revision 1.120 by root, Mon Feb 21 07:18:19 2011 UTC vs.
Revision 1.134 by root, Mon Jun 4 15:18:52 2012 UTC

1/*----------------------------------------------------------------------* 1/*----------------------------------------------------------------------*
2 * File: rxvttoolkit.C 2 * File: rxvttoolkit.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2003-2007 Marc Lehmann <pcg@goof.com> 6 * Copyright (c) 2003-2011 Marc Lehmann <schmorp@schmorp.de>
7 * Copyright (c) 2011 Emanuele Giaquinta <e.giaquinta@glauco.it> 7 * Copyright (c) 2011 Emanuele Giaquinta <e.giaquinta@glauco.it>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
66#endif 66#endif
67#if USE_XIM 67#if USE_XIM
68 "WM_LOCALE_NAME", 68 "WM_LOCALE_NAME",
69 "XIM_SERVERS", 69 "XIM_SERVERS",
70#endif 70#endif
71#ifdef ENABLE_TRANSPARENCY 71#if ENABLE_TRANSPARENCY
72 "_XROOTPMAP_ID", 72 "_XROOTPMAP_ID",
73 "ESETROOT_PMAP_ID", 73 "ESETROOT_PMAP_ID",
74#endif 74#endif
75#if ENABLE_XEMBED 75#if ENABLE_XEMBED
76 "_XEMBED", 76 "_XEMBED",
153 put (*this->begin ()); 153 put (*this->begin ());
154} 154}
155 155
156///////////////////////////////////////////////////////////////////////////// 156/////////////////////////////////////////////////////////////////////////////
157 157
158#ifdef USE_XIM 158#if USE_XIM
159 159
160static void 160static void
161#if XIMCB_PROTO_BROKEN 161#if XIMCB_PROTO_BROKEN
162im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3) 162im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3)
163#else 163#else
430bool rxvt_display::ref_init () 430bool rxvt_display::ref_init ()
431{ 431{
432#ifdef LOCAL_X_IS_UNIX 432#ifdef LOCAL_X_IS_UNIX
433 if (id[0] == ':') 433 if (id[0] == ':')
434 { 434 {
435 if (!(val = rxvt_temp_buf<char> (5 + strlen (id) + 1))) 435 char *val = rxvt_temp_buf<char> (5 + strlen (id) + 1);
436 return false; 436
437 strcpy (val, "unix/"); 437 strcpy (val, "unix/");
438 strcat (val, id); 438 strcat (val, id);
439
439 dpy = XOpenDisplay (val); 440 dpy = XOpenDisplay (val);
440 } 441 }
441 else 442 else
442#endif 443#endif
443 dpy = 0; 444 dpy = 0;
449 return false; 450 return false;
450 451
451 screen = DefaultScreen (dpy); 452 screen = DefaultScreen (dpy);
452 root = DefaultRootWindow (dpy); 453 root = DefaultRootWindow (dpy);
453 454
454 assert (ARRAY_LENGTH(xa_names) == NUM_XA); 455 assert (ecb_array_length (xa_names) == NUM_XA);
455 XInternAtoms (dpy, (char **)xa_names, NUM_XA, False, xa); 456 XInternAtoms (dpy, (char **)xa_names, NUM_XA, False, xa);
456 457
457 XrmSetDatabase (dpy, get_resources (false)); 458 XrmSetDatabase (dpy, get_resources (false));
458 459
459#ifdef POINTER_BLANK 460#ifdef POINTER_BLANK
465 blank_cursor = XCreateGlyphCursor (dpy, f, f, ' ', ' ', 466 blank_cursor = XCreateGlyphCursor (dpy, f, f, ' ', ' ',
466 &blackcolour, &blackcolour); 467 &blackcolour, &blackcolour);
467 XUnloadFont (dpy, f); 468 XUnloadFont (dpy, f);
468#endif 469#endif
469 470
471 flags = 0;
472#if XRENDER
473 int major, minor;
474 if (XRenderQueryVersion (dpy, &major, &minor))
475 {
476 flags |= DISPLAY_HAS_RENDER;
477
478 if (major > 0 || (major == 0 && minor >= 11))
479 flags |= DISPLAY_HAS_RENDER_MUL;
480
481 XFilters *filters = XRenderQueryFilters (dpy, root);
482 if (filters)
483 {
484 for (int i = 0; i < filters->nfilter; i++)
485 if (!strcmp (filters->filter[i], FilterConvolution))
486 flags |= DISPLAY_HAS_RENDER_CONV;
487
488 XFree (filters);
489 }
490 }
491#endif
492
470 int fd = XConnectionNumber (dpy); 493 int fd = XConnectionNumber (dpy);
471 494
472 // try to detect whether we have a local connection. 495 // try to detect whether we have a local connection.
473 // assume unix domain socket == local, everything else not 496 // assume unix domain socket == local, everything else not
474 // TODO: might want to check for inet/127.0.0.1 497 // TODO: might want to check for inet/127.0.0.1
511#ifdef POINTER_BLANK 534#ifdef POINTER_BLANK
512 XFreeCursor (dpy, blank_cursor); 535 XFreeCursor (dpy, blank_cursor);
513#endif 536#endif
514 x_ev.stop (); 537 x_ev.stop ();
515 flush_ev.stop (); 538 flush_ev.stop ();
516#ifdef USE_XIM 539#if USE_XIM
517 xims.clear (); 540 xims.clear ();
518#endif 541#endif
519 XrmDestroyDatabase (XrmGetDatabase (dpy)); 542 XrmDestroyDatabase (XrmGetDatabase (dpy));
520 XCloseDisplay (dpy); 543 XCloseDisplay (dpy);
521} 544}
522 545
523#ifdef USE_XIM 546#if USE_XIM
524void rxvt_display::im_change_cb () 547void rxvt_display::im_change_cb ()
525{ 548{
526 for (im_watcher **i = imw.begin (); i != imw.end (); ++i) 549 for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
527 (*i)->call (); 550 (*i)->call ();
528} 551}
564 do 587 do
565 { 588 {
566 XEvent xev; 589 XEvent xev;
567 XNextEvent (dpy, &xev); 590 XNextEvent (dpy, &xev);
568 591
569#ifdef USE_XIM 592#if USE_XIM
570 if (!XFilterEvent (&xev, None)) 593 if (!XFilterEvent (&xev, None))
571 { 594 {
572 if (xev.type == PropertyNotify 595 if (xev.type == PropertyNotify
573 && xev.xany.window == root 596 && xev.xany.window == root
574 && xev.xproperty.atom == xa[XA_XIM_SERVERS]) 597 && xev.xproperty.atom == xa[XA_XIM_SERVERS])
582 if (!xw[i]) 605 if (!xw[i])
583 xw.erase_unordered (i); 606 xw.erase_unordered (i);
584 else if (xw[i]->window == xev.xany.window) 607 else if (xw[i]->window == xev.xany.window)
585 xw[i]->call (xev); 608 xw[i]->call (xev);
586 } 609 }
587#ifdef USE_XIM 610#if USE_XIM
588 } 611 }
589#endif 612#endif
590 } 613 }
591 while (XEventsQueued (dpy, QueuedAlready)); 614 while (XEventsQueued (dpy, QueuedAlready));
592 615
623 } 646 }
624 647
625 cur_owner = owner; 648 cur_owner = owner;
626} 649}
627 650
628#ifdef USE_XIM 651#if USE_XIM
629 652
630void rxvt_display::reg (im_watcher *w) 653void rxvt_display::reg (im_watcher *w)
631{ 654{
632 imw.push_back (w); 655 imw.push_back (w);
633} 656}
668Atom rxvt_display::atom (const char *name) 691Atom rxvt_display::atom (const char *name)
669{ 692{
670 return XInternAtom (dpy, name, False); 693 return XInternAtom (dpy, name, False);
671} 694}
672 695
696Pixmap
697rxvt_display::get_pixmap_property (Atom property)
698{
699 Pixmap pixmap = None;
700
701 int aformat;
702 unsigned long nitems, bytes_after;
703 Atom atype;
704 unsigned char *prop;
705 int result = XGetWindowProperty (dpy, root, property,
706 0L, 1L, False, XA_PIXMAP, &atype, &aformat,
707 &nitems, &bytes_after, &prop);
708 if (result == Success)
709 {
710 if (atype == XA_PIXMAP)
711 pixmap = *(Pixmap *)prop;
712 XFree (prop);
713 }
714
715 return pixmap;
716}
717
673///////////////////////////////////////////////////////////////////////////// 718/////////////////////////////////////////////////////////////////////////////
674 719
675template class refcache<rxvt_display>; 720template class refcache<rxvt_display>;
676refcache<rxvt_display> displays; 721refcache<rxvt_display> displays;
677 722
686 731
687bool 732bool
688rxvt_color::alloc (rxvt_screen *screen, const rgba &color) 733rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
689{ 734{
690 //TODO: only supports 24 bit 735 //TODO: only supports 24 bit
691 int alpha = color.a >= 0xff00 ? 0xffff : color.a; 736 unsigned int alpha = color.a >= 0xff00 ? 0xffff : color.a;
692 737
693#if XFT 738#if XFT
694 XRenderPictFormat *format; 739 XRenderPictFormat *format;
695 740
696 // FUCKING Xft gets it wrong, of course, so work around it. 741 // FUCKING Xft gets it wrong, of course, so work around it.
703 c.color.red = color.r; 748 c.color.red = color.r;
704 c.color.green = color.g; 749 c.color.green = color.g;
705 c.color.blue = color.b; 750 c.color.blue = color.b;
706 c.color.alpha = alpha; 751 c.color.alpha = alpha;
707 752
753 // Xft wants premultiplied alpha, but abuses the alpha channel
754 // as blend factor, and doesn't allow us to set the alpha channel
755 c.color.red = c.color.red * alpha / 0xffff;
756 c.color.green = c.color.green * alpha / 0xffff;
757 c.color.blue = c.color.blue * alpha / 0xffff;
758
708 c.pixel = insert_component (color.r, format->direct.redMask , format->direct.red ) 759 c.pixel = insert_component (c.color.red , format->direct.redMask , format->direct.red )
709 | insert_component (color.g, format->direct.greenMask, format->direct.green) 760 | insert_component (c.color.green, format->direct.greenMask, format->direct.green)
710 | insert_component (color.b, format->direct.blueMask , format->direct.blue ) 761 | insert_component (c.color.blue , format->direct.blueMask , format->direct.blue )
711 | insert_component (alpha , format->direct.alphaMask, format->direct.alpha); 762 | insert_component (alpha , format->direct.alphaMask, format->direct.alpha);
712 763
713 return true; 764 return true;
714 } 765 }
715 else 766 else
716 { 767 {
719 d.red = color.r; 770 d.red = color.r;
720 d.green = color.g; 771 d.green = color.g;
721 d.blue = color.b; 772 d.blue = color.b;
722 d.alpha = alpha; 773 d.alpha = alpha;
723 774
724 return XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c); 775 if (XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c))
776 return true;
725 } 777 }
726#else 778#else
727 c.red = color.r; 779 c.red = color.r;
728 c.green = color.g; 780 c.green = color.g;
729 c.blue = color.b; 781 c.blue = color.b;
730 782
731 if (screen->visual->c_class == TrueColor) 783 if (screen->visual->c_class == TrueColor)
732 { 784 {
733 c.pixel = (color.r >> (16 - rxvt_popcount (screen->visual->red_mask )) << rxvt_ctz (screen->visual->red_mask )) 785 c.pixel = (color.r >> (16 - ecb_popcount32 (screen->visual->red_mask )) << ecb_ctz32 (screen->visual->red_mask ))
734 | (color.g >> (16 - rxvt_popcount (screen->visual->green_mask)) << rxvt_ctz (screen->visual->green_mask)) 786 | (color.g >> (16 - ecb_popcount32 (screen->visual->green_mask)) << ecb_ctz32 (screen->visual->green_mask))
735 | (color.b >> (16 - rxvt_popcount (screen->visual->blue_mask )) << rxvt_ctz (screen->visual->blue_mask )); 787 | (color.b >> (16 - ecb_popcount32 (screen->visual->blue_mask )) << ecb_ctz32 (screen->visual->blue_mask ));
736 788
737 return true; 789 return true;
738 } 790 }
739 else if (XAllocColor (screen->dpy, screen->cmap, &c)) 791 else if (XAllocColor (screen->dpy, screen->cmap, &c))
740 return true; 792 return true;
741 else 793#endif
794
742 c.pixel = (color.r + color.g + color.b) > 128*3 795 c.pixel = (color.r + color.g + color.b) > 128*3
743 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy)) 796 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy))
744 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy)); 797 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy));
745#endif
746 798
747 return false; 799 return false;
748} 800}
749 801
750bool 802bool
892 lerp (c.a, to.a, percent) 944 lerp (c.a, to.a, percent)
893 ) 945 )
894 ); 946 );
895} 947}
896 948
897rxvt_selection::rxvt_selection (rxvt_display *disp, int selnum, Time tm, Window win, Atom prop, rxvt_term *term, void *cb_sv) 949rxvt_selection::rxvt_selection (rxvt_display *disp, int selnum, Time tm, Window win, Atom prop, rxvt_term *term)
898: display (disp), request_time (tm), request_win (win), request_prop (prop), term (term), cb_sv (cb_sv) 950: display (disp), request_time (tm), request_win (win), request_prop (prop), term (term)
899{ 951{
900 assert (selnum >= Sel_Primary && selnum <= Sel_Clipboard); 952 assert (selnum >= Sel_Primary && selnum <= Sel_Clipboard);
901 953
902 timer_ev.set<rxvt_selection, &rxvt_selection::timer_cb> (this); 954 timer_ev.set<rxvt_selection, &rxvt_selection::timer_cb> (this);
903 timer_ev.repeat = 10.; 955 timer_ev.repeat = 10.;
905 957
906 incr_buf = 0; 958 incr_buf = 0;
907 incr_buf_size = incr_buf_fill = 0; 959 incr_buf_size = incr_buf_fill = 0;
908 selection_wait = Sel_normal; 960 selection_wait = Sel_normal;
909 selection_type = selnum; 961 selection_type = selnum;
962 cb_sv = 0;
910} 963}
911 964
912void 965void
913rxvt_selection::stop () 966rxvt_selection::stop ()
914{ 967{
925 978
926void 979void
927rxvt_selection::run () 980rxvt_selection::run ()
928{ 981{
929 int selnum = selection_type; 982 int selnum = selection_type;
983
984#if ENABLE_FRILLS
985 if (selnum == Sel_Primary && display->selection_owner)
986 {
987 /* internal selection */
988 char *str = rxvt_wcstombs (display->selection_owner->selection.text, display->selection_owner->selection.len);
989 finish (str, strlen (str));
990 free (str);
991 return;
992 }
993#endif
930 994
931#if X_HAVE_UTF8_STRING 995#if X_HAVE_UTF8_STRING
932 selection_type = Sel_UTF8String; 996 selection_type = Sel_UTF8String;
933 if (request (display->xa[XA_UTF8_STRING], selnum)) 997 if (request (display->xa[XA_UTF8_STRING], selnum))
934 return; 998 return;
943} 1007}
944 1008
945void 1009void
946rxvt_selection::finish (char *data, unsigned int len) 1010rxvt_selection::finish (char *data, unsigned int len)
947{ 1011{
948 if (term) 1012 if (!cb_sv)
949 { 1013 {
950 if (data) 1014 if (data)
951 term->paste (data, len); 1015 term->paste (data, len);
952 1016
953 term->selection_req = 0; 1017 term->selection_req = 0;
954 delete this; 1018 delete this;
955 } 1019 }
956#if ENABLE_PERL 1020#if ENABLE_PERL
957 else 1021 else
958 { 1022 {
959 stop (); 1023 stop (); // we do not really trust perl callbacks
960 abort (); //TODO 1024 rxvt_perl.selection_finish (this, data, len);
961 } 1025 }
962#endif 1026#endif
963} 1027}
964 1028
965bool 1029bool
1160 handle_selection (xev.xproperty.window, xev.xproperty.atom, true); 1224 handle_selection (xev.xproperty.window, xev.xproperty.atom, true);
1161 break; 1225 break;
1162 1226
1163 case SelectionNotify: 1227 case SelectionNotify:
1164 if (selection_wait == Sel_normal 1228 if (selection_wait == Sel_normal
1165 && xev.xselection.time == request_time 1229 && xev.xselection.time == request_time)
1166 && xev.xselection.property == request_prop)
1167 { 1230 {
1168 timer_ev.stop (); 1231 timer_ev.stop ();
1169 handle_selection (xev.xselection.requestor, xev.xselection.property, true); 1232 handle_selection (xev.xselection.requestor, xev.xselection.property, true);
1170 } 1233 }
1171 break; 1234 break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines