🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.emacs.bug
Article #98658

emacs-18.57 with highlighting and X11 problems

#98658
From: Jon A. Tankersley
Date: Tue, 23 Apr 1991 17:32
608 lines
20377 bytes
Enclosed are patches to fix a mouse-highlighting problem and to enable
-iconic to work on the command line for emacs.  These are not my patches, but
rather some I picked up from others that appear to work.  They never posted
them to you.

>From mwette@mr-ed.Jpl.Nasa.Gov Thu Mar 28 12:41:01 1991
To: zjat02@trc.amoco.com (Jon A. Tankersley)
Subject: iconify patch

Jon A. Tankersley writes:
|> Have you tried your patch with 18.57?  It works, but it tries to edit
|> the file -iconic.  Any ideas?

I just got this extra fix from Scott Lawrence <lawrence@epps.kodak.com>.
He also says
  "As with some of the other switches, the '-iconic' switch must fall
  in a particular place; in this case, between '-d' (sets the display)
  and '-nw' (no window).  Seems to work just fine."

*** src/emacs.c.orig	Thu Mar 28 09:11:04 1991
--- src/emacs.c	Thu Mar 28 08:32:22 1991
***************
*** 283,288 ****
--- 283,296 ----
      } 
    else
      alternate_display = 0;
+ 
+   if (skip_args + 1 < argc
+       && (!strcmp (argv[skip_args + 1], "-iconic")))
+     {
+       skip_args += 1;
+       /* Actual implementation of -iconic is in x11term.c */
+       /* This just keeps it from being treated as a file  */
+     }
  #endif	/* HAVE_X_WINDOWS */
  
    if (skip_args + 1 < argc


>From laprade@trantor.harris-atd.com Thu Apr  4 09:42:05 1991
To: zjat02@trc.amoco.com (Jon A. Tankersley)
Subject: Re: hilight patch, the original posting

> I missed that one (actually didn't know I needed it until a user complained). Could you send a copy of Herrb's patch to me?

Here it is as I changed it:
--------------------
*** src/x11fns.c.orig	Tue Jan 15 19:07:14 1991
--- src/x11fns.c	Tue Feb 19 10:38:12 1991
***************
*** 108,114 ****
  
  extern XFontStruct *fontinfo;
  extern Font XXfid;
! extern GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp;
  extern XGCValues XXgcv;
  extern int XXfontw,XXfonth,XXbase,XXisColor;
  extern Colormap XXColorMap;
--- 108,114 ----
  
  extern XFontStruct *fontinfo;
  extern Font XXfid;
! extern GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp,XXgc_highlight;
  extern XGCValues XXgcv;
  extern int XXfontw,XXfonth,XXbase,XXisColor;
  extern Colormap XXColorMap;
***************
*** 200,206 ****
  
  	XSetForeground(XXdisplay, XXgc_norm, fore);
  	XSetBackground(XXdisplay, XXgc_rev, fore);
! 	
  	Fredraw_display ();
  	UNBLOCK_INPUT ();
  
--- 200,209 ----
  
  	XSetForeground(XXdisplay, XXgc_norm, fore);
  	XSetBackground(XXdisplay, XXgc_rev, fore);
! 	 
!  	XSetForeground(XXdisplay, XXgc_highlight, back ^ fore);
!   	XSetBackground(XXdisplay, XXgc_highlight, back ^ fore);	
!  
  	Fredraw_display ();
  	UNBLOCK_INPUT ();
  
***************
*** 241,246 ****
--- 244,253 ----
  
  	XSetBackground (XXdisplay, XXgc_norm, back);
  	XSetForeground (XXdisplay, XXgc_rev, back);
+ 
+         XSetForeground(XXdisplay, XXgc_highlight, back ^ fore);
+         XSetBackground(XXdisplay, XXgc_highlight, back ^ fore);
+ 
  	XSetForeground (XXdisplay, XXgc_curs, back);
  	XSetWindowBackground(XXdisplay, XXwindow, back);
  	XClearArea (XXdisplay, XXwindow, 0, 0,
***************
*** 906,911 ****
--- 913,1064 ----
  #endif				/* subprocesses */
  }
  
+ #define BACKWARD 0
+ #define FORWARD 1
+ #define	Cdt(r,c)		((r) * width + (c))
+ #define	CdRow(c)    		((c) / width)
+ #define	CdCol(c)               ((c) % width)
+  
+ DEFUN("do-highlight", Fdo_highlight, Sdo_highlight, 3, 3, 0, 
+       "Track the mouse and highlight until button is released. \
+         This just highlights a rectangular region between the \
+         specified row and column and the mouse position.")
+      (window, Col, Row)
+      Lisp_Object window, Col, Row;
+ {
+   int col, row, last_x, last_y, rx, ry, wx,wy, mask;
+   int last_highlight_pos, fake_mark, highlight_direction;
+   Window w, child;
+   int moved = 0;
+   int left,top,width,height;
+   BLOCK_INPUT_DECLARE ();
+ 
+   CHECK_WINDOW (window, 2);
+ 
+   left = XWINDOW (window)->left; /* window edges in the X window */
+   top = XWINDOW (window)->top;
+   width = XWINDOW (window)->width;
+   height = XWINDOW (window)->height;
+ 
+   if (window == minibuf_window)
+     {
+       left += minibuf_prompt_width;
+     }
+   else
+     height --;
+   
+   col = XINT(Col);
+   row = XINT(Row);
+   last_highlight_pos = fake_mark =  Cdt(row,col);
+   last_x = col;
+   last_y = row;
+   highlight_direction = -1;
+   BLOCK_INPUT ();
+ 
+   XQueryPointer(XXdisplay,XXwindow,&w, &child, &rx, &ry, &wx,&wy,&mask);
+   while((mask & ~0xff) != 0) {
+     row = wy  / XXfonth - top;
+     col = wx  / XXfontw - left;
+ 
+     if (row < 0) row = 0;
+     if (col < 0) col = 0;
+     if (row > height-1) row = height-1;
+     if (col > width-1) col = width-1;
+ 
+     if (!moved && Cdt(row,col) != last_highlight_pos){
+       moved = 1;
+       if (CursorExists) CursorToggle ();
+     };
+ 
+     Track_Text(left,top,width,row,col,last_x,last_y,&last_highlight_pos,&highlight_direction,fake_mark);
+     XQueryPointer(XXdisplay,XXwindow,&w, &child, &rx, &ry, &wx, &wy,&mask);
+   }; /* while */
+ 
+   Text_Hiliter(left,top,width,last_y,last_x,row,col); /* remove highlighted text */
+ 
+   UNBLOCK_INPUT ();
+ 
+   if (!CursorExists)
+     CursorToggle ();
+ }
+ 
+ Track_Text(left,top,width,trow,tcol,last_x,last_y,last_highlight_pos,highlight_direction,fake_mark)
+      int left,top,width;
+      register int trow, tcol;
+      int  *last_highlight_pos, *highlight_direction, fake_mark;
+ {
+   int  tpos;
+   int new_dir;
+   tpos = Cdt(trow, tcol);
+   
+   if(tpos == *last_highlight_pos)
+     return;
+   
+   if(*highlight_direction == -1)  
+     if(tpos > fake_mark)
+       *highlight_direction = FORWARD;
+     else
+       *highlight_direction = BACKWARD;
+   
+   if(tpos > fake_mark) 
+     new_dir = FORWARD;
+   else
+     new_dir = BACKWARD;
+   
+   if(new_dir != *highlight_direction){ 
+     Text_Hiliter(left,top,width,last_y, last_x,
+ 		 CdRow (*last_highlight_pos),CdCol (*last_highlight_pos));
+     *last_highlight_pos = fake_mark;
+     *highlight_direction = new_dir;
+   }           
+   Text_Hiliter(left,top,width,trow, tcol, CdRow (*last_highlight_pos), CdCol (*last_highlight_pos));
+   *last_highlight_pos = tpos;
+ }
+ 
+ Text_Hiliter(left,top,width,frow, fcol, trow, tcol)
+      int left,top,width;
+      int frow, fcol, trow, tcol;
+ {
+   int i;
+   if (frow == trow){
+     if(fcol > tcol){
+       i = fcol; fcol = tcol; tcol = i;
+     }
+     XFillRectangle( XXdisplay, XXwindow, XXgc_highlight,
+ 		   (left + fcol) * XXfontw,
+ 		   (top + frow) * XXfonth,
+ 		   (tcol - fcol) * XXfontw,
+ 		   XXfonth);
+   }
+   else{
+     if(frow > trow){
+       i = fcol; fcol = tcol; tcol = i;
+       i = frow; frow = trow; trow = i;
+     } 
+     
+     if(width > fcol)    /* If statements due to some bug in X11? */
+       XFillRectangle( XXdisplay, XXwindow, XXgc_highlight,
+ 		     (left + fcol) * XXfontw,
+ 		     (top + frow) * XXfonth,
+ 		     (width - fcol) * XXfontw,
+ 		     XXfonth);
+     
+     if(trow - frow > 1)
+       XFillRectangle( XXdisplay, XXwindow, XXgc_highlight,
+ 		     left * XXfontw,
+  		     (top + (1 + frow)) * XXfonth,
+  		     width * XXfontw,
+  		     (trow - frow - 1) * XXfonth);
+     if(tcol != 0)    
+       XFillRectangle( XXdisplay, XXwindow, XXgc_highlight,
+  		     left * XXfontw,
+  		     (top + trow) * XXfonth,
+  		     tcol * XXfontw,
+  		     XXfonth);
+     
+   }
+ } 
+ 
  syms_of_xfns ()
  {
    /* If not dumping, init_display ran before us, so don't override it.  */
***************
*** 956,961 ****
--- 1102,1108 ----
    defsubr (&Sx_rebind_keys);
  #endif notdef
    defsubr (&Sx_debug);
+   defsubr (&Sdo_highlight);
  }
  
  #endif /* HAVE_X_WINDOWS */
*** src/x11term.c.orig	Thu Jan 24 18:36:53 1991
--- src/x11term.c	Tue Feb 19 10:34:16 1991
***************
*** 213,219 ****
  Display *XXdisplay;
  int XXscreen;
  Window XXwindow;
! GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp;
  XGCValues XXgcv;
  Cursor EmacsCursor;
  Pixmap SinkPixmap, SinkMaskPixmap;
--- 213,219 ----
  Display *XXdisplay;
  int XXscreen;
  Window XXwindow;
! GC XXgc_norm,XXgc_rev,XXgc_curs,XXgc_temp,XXgc_highlight;
  XGCValues XXgcv;
  Cursor EmacsCursor;
  Pixmap SinkPixmap, SinkMaskPixmap;
***************
*** 2508,2513 ****
--- 2508,2521 ----
      XXgc_curs = XCreateGC(XXdisplay, XXwindow,
  			  GCFont|GCForeground|GCBackground,
  			  &XXgcv);
+ 
+     XXgcv.foreground = back ^ fore;
+     XXgcv.background = fore ^ back;
+     XXgc_highlight = XCreateGC(XXdisplay, XXwindow,
+   	     		       GCForeground|GCBackground,
+   			       &XXgcv);
+ 
+     XSetFunction(XXdisplay,XXgc_highlight, GXxor);
  
      EmacsCursor = XCreateFontCursor(XXdisplay, XC_left_ptr);
  
*** lisp/x-mouse.el.orig	Wed Jan  9 23:10:06 1991
--- lisp/x-mouse.el	Tue Feb 19 10:34:12 1991
***************
*** 84,89 ****
--- 84,96 ----
  (defconst x-button-c-m-s-middle-up (char-to-string 117))
  (defconst x-button-c-m-s-left-up (char-to-string 118))
  
+ (defvar last-mouse-x 0)
+ (defvar last-mouse-y 0)
+ 
+ (defvar ange-last-window nil)
+ (defvar ange-last-point nil)
+ 
+ (defvar highlight-point nil)
  (defvar x-process-mouse-hook nil
    "Hook to run after each mouse event is processed.  Should take two
  arguments; the first being a list (XPOS YPOS) corresponding to character
***************
*** 132,137 ****
--- 139,169 ----
    (if (x-mouse-select arg)
        (split-window-vertically nil)))
  
+ (defun x-mouse-extend-region (arg)
+   "Extend the mouse selected region, highlighting from the starting point of \
+    the last highlighted region, instead on the current mouse position"
+   (if (x-mouse-select arg)
+       (if highlight-point
+ 	  (if (< highlight-point (window-start))
+ 	      (do-highlight (selected-window) 0 0)
+ 	    (do-highlight (selected-window) last-mouse-x last-mouse-y)))))
+ 
+ (defun x-mouse-set-point-and-highlight (arg)
+   "Select Emacs window mouse is on, move point to mouse position, and track \
+    the mouse motion, highlighting between the point and mouse position until \
+    the mouse button is released"
+   (let* ((relative-coordinate (x-mouse-select arg))
+ 	 (rel-x (car relative-coordinate))
+ 	 (rel-y (car (cdr relative-coordinate))))
+     (if relative-coordinate
+ 	(progn
+           (setq last-mouse-x rel-x)
+           (setq last-mouse-y rel-y)
+           (setq highlight-point (point))
+           (do-highlight (selected-window) rel-x rel-y)
+ 	  (move-to-window-line rel-y)
+ 	  (move-to-column (+ rel-x (current-column)))))))
+ 
  (defun x-mouse-set-point (arg)
    "Select Emacs window mouse is on, and move point to mouse position."
    (let* ((relative-coordinate (x-mouse-select arg))
***************
*** 178,183 ****
--- 210,249 ----
    "Kill text between point and mouse; also copy to window system cut buffer."
    (x-cut-text arg t))
  
+ (defun ange-x-mouse-highlight (arg)
+   (setq ange-last-window (selected-window))
+   (setq ange-last-point (point))
+   (x-mouse-set-point-and-highlight arg))
+ 
+ (defun ange-x-cut-text (arg)
+   "If there is a region, then cut the text from the region, and restore
+ the window and point to the saved position. If there is no region, then 
+ do nothing at all."
+   (if (and ange-last-window ange-last-point)
+       (progn
+ 	(if (coordinates-in-window-p arg (selected-window))
+ 	    (progn
+ 	      (let (beg end (opoint (point)))
+ 		(setq opoint (point))
+ 		(save-excursion
+ 		  (x-mouse-set-point arg)
+ 		  (setq beg (min opoint (point))
+ 			end (max opoint (point)))
+ 		  (if (eq beg end)
+ 		      (progn
+ 			(setq ange-last-window (selected-window))
+ 			(setq ange-last-point (point)))
+ 		    (x-store-cut-buffer (buffer-substring beg end))
+ 		    (copy-region-as-kill beg end)))))
+ 	  (message "Mouse not in selected window"))
+ 	(select-window ange-last-window)
+ 	(goto-char ange-last-point)
+ 	(setq ange-last-window nil)
+ 	(setq ange-last-point nil))))
+ 
+ (defun ange-x-paste-text-at-text-cursor (arg)
+   (insert (x-get-cut-buffer)))
+ 
  (defun x-mouse-ignore (arg)
    "Don't do anything.")
  
***************
*** 274,279 ****
        (define-key mouse-map x-button-right 'x-mouse-select)
        (define-key mouse-map x-button-left 'x-mouse-set-mark)
        (define-key mouse-map x-button-middle 'x-mouse-set-point))
!   (define-key mouse-map x-button-right 'x-cut-text)
!   (define-key mouse-map x-button-left 'x-mouse-set-point)
!   (define-key mouse-map x-button-middle 'x-paste-text))
--- 340,349 ----
        (define-key mouse-map x-button-right 'x-mouse-select)
        (define-key mouse-map x-button-left 'x-mouse-set-mark)
        (define-key mouse-map x-button-middle 'x-mouse-set-point))
!   (define-key mouse-map x-button-left 'ange-x-mouse-highlight)
!   (define-key mouse-map x-button-left-up 'ange-x-cut-text)
!   (define-key mouse-map x-button-right 'ange-x-paste-text-at-text-cursor)
!   (define-key mouse-map x-button-right-up 'x-mouse-ignore)
! )
! 
! 

---
Ken Laprade			INTERNET: laprade@trantor.harris-atd.com
Harris Corporation 		Usenet:  ...!uunet!x102a!trantor!laprade
PO Box 37, MS 3A/1912		Voice: (407)727-4433
Melbourne, FL 32902		FAX: (407)729-3363

>From ztlf0a@gpsd Thu Apr  4 09:06:40 1991
To: zjat02@crsa
Subject: Patch to patch to hilight selection under X11 for 18.57

[forwarding note from: Ken Laprade]


this guy refers to two previous patches that i didn't catch. do
you happen to have them?  right now i just have to guess whether
i'm copying/cutting the portion i want from an emacs window because
mouse grabbing doesn't do the correct highlighting.

(i'm sure you're wishing i'd stayed with sunview by now... :-)

terri.

------- Start of forwarded message -------
Newsgroups: gnu.emacs.sources
Summary: Fix to previous patch so hilight works right in minibuffer
Organization: Advanced Technology Dept., Harris Corp., Melbourne, Fl
From: laprade@ringworld.harris-atd.com (Ken Laprade)
Subject: Patch to patch to hilight selection under X11 for 18.57
Date: 2 Apr 91 21:01:26 GMT


A month or so ago Matthieu Herrb <matthieu@laas.fr> posted an updated
version (for emacs 18.57) of Andy Norman's <ange@hplb.hpl.hp.com> patch to
do highlighting of mouse drags under X11.  Here is an additional patch that
fixes do-highlight so that it works in the minibuffer.
- --------------------
*** src/x11fns.c~	Tue Feb 26 15:58:37 1991
- --- src/x11fns.c	Mon Apr  1 17:25:11 1991
***************
*** 940,945 ****
- --- 940,952 ----
    width = XWINDOW (window)->width;
    height = XWINDOW (window)->height;
  
+   if (window == minibuf_window)
+     {
+       left += minibuf_prompt_width;
+     }
+   else
+     height --;
+   
    col = XINT(Col);
    row = XINT(Row);
    last_highlight_pos = fake_mark =  Cdt(row,col);
***************
*** 955,961 ****
  
      if (row < 0) row = 0;
      if (col < 0) col = 0;
!     if (row > height-2) row = height-2;
      if (col > width-1) col = width-1;
  
      if (!moved && Cdt(row,col) != last_highlight_pos){
- --- 962,968 ----
  
      if (row < 0) row = 0;
      if (col < 0) col = 0;
!     if (row > height-1) row = height-1;
      if (col > width-1) col = width-1;
  
      if (!moved && Cdt(row,col) != last_highlight_pos){

- --------------------
Has anybody figured out how to fix (or use) do-highlight so that the
up-event is not delayed?  The symptom I see occurs when a mouse button has
functions bound to both the down and up presses and the down press function
calls do-highlight.  The up function does not seem to be called when the
button is released.  Rather it is executed when the next X event is
processed, like when a button or key is pressed - even just a shift key.

- ---
Ken Laprade			INTERNET: laprade@trantor.harris-atd.com
Harris Corporation 		Usenet:  ...!uunet!x102a!trantor!laprade
PO Box 37, MS 3A/1912		Voice: (407)727-4433
Melbourne, FL 32902		FAX: (407)729-3363
------- End of forwarded message -------

>From ztlf0a@gpsd Fri Mar 22 09:36:08 1991
To: zjat02@crsa
Subject: News: patch for making emacs iconify under X11

our current emacs' inablitiy to iconify at startup is one reason
i have yet to switch over to X.  does this patch look valid?
could i try it in some test version of emacs? 

-------- Forwarding from newsgroup gnu.emacs.sources --------

From: mwette@mr-ed.jpl.nasa.gov (Matt Wette)
Newsgroups: gnu.emacs.sources
Subject: patch for making emacs iconify under X11
Date: 21 Mar 91 15:11:47 GMT
Reply-To: mwette@mr-ed.jpl.nasa.gov (Matt Wette)
Organization: Jet Propulsion Laboratory, Pasadena, CA
Nntp-Posting-Host: mr-ed.jpl.nasa.gov

The following is a patch for emacs-18.55 to enable it to start up
iconified in X11.  Changes are to the files src/x11term.c and
lisp/term/x-win.el.  Enjoy! --  Matt (mwette@mr-ed.jpl.nasa.gov)

*** src/x11term.c-orig	Wed Aug  2 19:56:42 1989
--- src/x11term.c	Fri Jan 11 07:46:45 1991
***************
*** 194,199 ****
--- 194,201 ----
  int XXInternalBorder;		/* Internal border width */
  int updated[MAXHEIGHT];
  
+ int XXinitial_state;		/* initial state (part of XWMHints) */
+ 
  static char  *temp_font;                /* needed because of loading hacks */
  static char  *temp_reverseVideo;
  static char  *temp_borderWidth;
***************
*** 1603,1608 ****
--- 1605,1612 ----
  	XXheader = (char *) NULL;
  
  	XXicon_usebitmap = 0;
+ 
+ 	XXinitial_state = NormalState;
  	
  	temp_font = "fixed";
  	progname = xargv[0];
***************
*** 1721,1726 ****
--- 1725,1735 ----
  			xxargc--;
  			xxargv++;
  		}
+ 		if (xxargc && !strcmp (*xxargv, "-iconic")) {
+ 			xxargc--;
+ 			xxargv++;
+ 			XXinitial_state = IconicState;
+ 		}
  		if (XXisColor) {
  			if ((xxargc > 1 && !strcmp (*xxargv, "-fg"))) {
  			        xxargc--;
***************
*** 2266,2272 ****
  	    wmhints.flags |= IconPixmapHint | IconMaskHint;
  
      wmhints.input = True;
!     wmhints.initial_state = NormalState;
  
      SinkPixmap = XCreateBitmapFromData (XXdisplay, w,
  					sink_bits, sink_width,
--- 2275,2281 ----
  	    wmhints.flags |= IconPixmapHint | IconMaskHint;
  
      wmhints.input = True;
!     wmhints.initial_state = XXinitial_state;
  
      SinkPixmap = XCreateBitmapFromData (XXdisplay, w,
  					sink_bits, sink_width,
*** lisp/term/x-win.el-orig	Tue Jun 20 11:03:45 1989
--- lisp/term/x-win.el	Fri Jan 11 07:55:34 1991
***************
*** 65,71 ****
  		  ("-bg" . x-ignore-arg)
  		  ("-bd" . x-ignore-arg)
  		  ("-cr" . x-ignore-arg)
! 		  ("-ms" . x-ignore-arg))
  		command-switch-alist)))
  
  (defun x-ignore-arg (&rest ignore)
--- 65,72 ----
  		  ("-bg" . x-ignore-arg)
  		  ("-bd" . x-ignore-arg)
  		  ("-cr" . x-ignore-arg)
! 		  ("-ms" . x-ignore-arg)
! 		  ("-iconic" . x-ignore-arg))
  		command-switch-alist)))
  
  (defun x-ignore-arg (&rest ignore)


-- 
 _________________________________________________________________
 Matthew R. Wette           | Jet Propulsion Laboratory, 198-326
 mwette@csi.jpl.nasa.gov    | 4800 Oak Grove Dr, Pasadena,CA 91109
 -----------------------------------------------------------------
-------- End of forwarded news message --------
Technical Details
Message-ID: <9104231732.AA19473@trc.amoco.com>
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!ira.uka.de!sol.ctr.columbia.edu!caen!dali.cs.montana.edu!bridge2!mips!apple!agate!usenet.ins.cwru.edu!tut.cis.ohio-state.edu!unreplyable!garbage

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fb2f1,ede4259e8d73d031,start
X-Google-Attributes: gidfb2f1,public
X-Google-ArrivalTime: 1991-04-24 02:30:27 PST
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!ira.uka.de!sol.ctr.columbia.edu!caen!dali.cs.montana.edu!bridge2!mips!apple!agate!usenet.ins.cwru.edu!tut.cis.ohio-state.edu!unreplyable!garbage
From: zjat02@trc.amoco.com (Jon A. Tankersley)
Newsgroups: gnu.emacs.bug
Subject: emacs-18.57 with highlighting and X11 problems
Message-ID: <9104231732.AA19473@trc.amoco.com>
Date: 23 Apr 91 17:32:55 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 608
Approved: bug-gnu-emacs@prep.ai.mit.edu