"Fossies" - the Fresh Open Source Software Archive

Member "jed-0.99-19/src/mouse.c" (14 Dec 2009, 12255 Bytes) of package /linux/misc/jed-0.99-19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mouse.c" see the Fossies "Dox" file reference documentation.

    1 /* -*- mode: C; mode: fold; -*- */
    2 /* Copyright (c) 1992, 1998, 2000, 2002, 2003, 2004, 2005, 2006 John E. Davis
    3  * This file is part of JED editor library source.
    4  *
    5  * You may distribute this file under the terms the GNU General Public
    6  * License.  See the file COPYING for more information.
    7  */
    8 #include "config.h"
    9 #include "jed-feat.h"
   10 /*{{{ Include Files */
   11 
   12 #include <stdio.h>
   13 #include <string.h>
   14 #include <slang.h>
   15 
   16 #ifdef HAS_MOUSE
   17 
   18 #include "jdmacros.h"
   19 
   20 #include "buffer.h"
   21 #include "sysdep.h"
   22 #include "keymap.h"
   23 #include "misc.h"
   24 #include "paste.h"
   25 #include "screen.h"
   26 #include "ledit.h"
   27 #include "ins.h"
   28 #include "display.h"
   29 #include "hooks.h"
   30 
   31 /*}}}*/
   32 
   33 int (*JMouse_Event_Hook)(void);
   34 void (*JMouse_Hide_Mouse_Hook) (int);
   35 
   36 /*{{{ Static Global Variables */
   37 
   38 static SLang_Name_Type *Jed_Default_Mouse_Down_Hook;
   39 static SLang_Name_Type *Jed_Mouse_Status_Down_Hook;
   40 static SLang_Name_Type *Jed_Default_Mouse_Up_Hook;
   41 static SLang_Name_Type *Jed_Mouse_Status_Up_Hook;
   42 static SLang_Name_Type *Jed_Default_Mouse_Drag_Hook;
   43 static SLang_Name_Type *Jed_Mouse_Status_Drag_Hook;
   44 
   45 #if JED_HAS_MULTICLICK
   46 static SLang_Name_Type *Jed_Mouse_Status_2Click_Hook;
   47 static SLang_Name_Type *Jed_Mouse_Status_3Click_Hook;
   48 static SLang_Name_Type *Jed_Default_Mouse_2Click_Hook;
   49 static SLang_Name_Type *Jed_Default_Mouse_3Click_Hook;
   50 #endif
   51 
   52 static Window_Type *Use_This_Window;
   53 static Window_Type *Save_Window;
   54 static unsigned int Down_Mask;
   55 
   56 #ifdef IBMPC_SYSTEM
   57 # define JED_MOUSE_MAX_QUEUE_SIZE 8
   58 #else
   59 # define JED_MOUSE_MAX_QUEUE_SIZE 64
   60 #endif
   61 static JMouse_Type Mouse_Queue [JED_MOUSE_MAX_QUEUE_SIZE];
   62 static JMouse_Type Current_Event;
   63 
   64 static int Mouse_Queue_Hint;
   65 
   66 
   67 static unsigned char Mouse_Button_Map [6] =
   68 {
   69    JMOUSE_BUTTON_1,
   70    JMOUSE_BUTTON_2,
   71    JMOUSE_BUTTON_3,
   72    JMOUSE_BUTTON_4,
   73    JMOUSE_BUTTON_5,
   74    JMOUSE_BUTTON_6
   75 };
   76 
   77 /*}}}*/
   78 
   79 #ifndef USE_GPM_MOUSE
   80 # if defined(__MSDOS__) 
   81 #  if !defined(MSWINDOWS)
   82 #   include "pcmouse.c"
   83 #  endif
   84 # else
   85 #  ifdef __os2__
   86 #   include "os2mouse.c"
   87 #  else
   88 int (*X_Open_Mouse_Hook)(void);
   89 void (*X_Close_Mouse_Hook)(void);
   90 #  endif /* os2 */
   91 # endif /* ibmpc */
   92 #endif /* NOT USE_GPM_MOUSE */
   93 
   94 
   95 #if JED_HAS_MENUS
   96 static int Hack_Hack = 1;
   97 static Window_Type *Non_Existent_Menu_Window = (Window_Type *)&Hack_Hack;
   98 #endif
   99 #define BUFFER_STATUS_LINE  1
  100 #define MENU_BAR_STATUS     2
  101 
  102 /* returns button number from map */
  103 static unsigned char m2b (int m)
  104 {
  105    switch (m)
  106      {
  107       default:
  108       case 0x01: return 0;
  109       case 0x02: return 1;
  110       case 0x04: return 2;
  111       case 0x08: return 3;
  112       case 0x10: return 4;
  113       case 0x20: return 5;
  114      }
  115 }
  116 
  117 /* *ap and *bp must have one of values in set (1, 2, 4, 8, 16, 32, 64).  */
  118 void jed_map_mouse_buttons (int *ap, int *bp) /*{{{*/
  119 {
  120    unsigned char a, b;
  121    
  122    a = m2b (*ap);
  123    b = m2b (*bp);
  124    
  125    if ((a > 5) || (b > 5)) return;
  126    
  127    Mouse_Button_Map [a] = b << 1;
  128 }
  129 
  130 /*}}}*/
  131 
  132 int jed_mouse_add_event (JMouse_Type *ev) /*{{{*/
  133 {
  134    int save = Mouse_Queue_Hint;
  135    /* Search the queue looking for an empty slot. */
  136    while (Mouse_Queue_Hint < JED_MOUSE_MAX_QUEUE_SIZE)
  137      {
  138     if (Mouse_Queue[Mouse_Queue_Hint].type == 0)
  139       {
  140          Mouse_Queue [Mouse_Queue_Hint] = *ev;
  141          return Mouse_Queue_Hint;
  142       }
  143     Mouse_Queue_Hint++;
  144      }
  145    
  146    Mouse_Queue_Hint = save;
  147    while (Mouse_Queue_Hint > 0)
  148      {
  149     Mouse_Queue_Hint--;
  150     if (Mouse_Queue[Mouse_Queue_Hint].type == 0)
  151       {
  152          Mouse_Queue [Mouse_Queue_Hint] = *ev;
  153          return Mouse_Queue_Hint;
  154       }
  155      }
  156    
  157    if (Input_Buffer_Len == 0)
  158      {
  159     jed_flush_mouse_queue ();
  160     Mouse_Queue [0] = *ev;
  161     return 0;
  162      }
  163    
  164    return -1;
  165 }
  166 
  167 /*}}}*/
  168 
  169 static JMouse_Type *get_mouse_event (unsigned int *type) /*{{{*/
  170 {
  171    int queue_pos;
  172    JMouse_Type *jm;
  173    
  174    /* Keyboard input should be ready.  If it is not, get out. */   
  175    if (0 == input_pending (&Number_Zero))
  176      return NULL;
  177    
  178    queue_pos = jed_getkey ();
  179    
  180    if ((queue_pos >= JED_MOUSE_MAX_QUEUE_SIZE) 
  181        || (queue_pos < 0))
  182      return NULL;
  183    
  184    jm = Mouse_Queue + queue_pos;
  185    /* 1, 2, 4, 8,..., 32 --> Mouse_Button_Map of 0, 1, 2, ... 5 */
  186    jm->button = Mouse_Button_Map [m2b(jm->button)];
  187    *type = jm->type;
  188    jm->type = 0;
  189    
  190    Mouse_Queue_Hint = queue_pos;
  191    
  192    return jm;
  193 }
  194 
  195 /*}}}*/
  196 
  197 void jed_mouse_get_event_info (void) /*{{{*/
  198 {
  199    SLang_push_integer (Current_Event.x);
  200    SLang_push_integer (Current_Event.y);
  201    SLang_push_integer (Current_Event.state);
  202 }
  203 
  204 /*}}}*/
  205 
  206 void jed_flush_mouse_queue (void) /*{{{*/
  207 {
  208    unsigned int i;
  209    
  210    for (i = 0; i < JED_MOUSE_MAX_QUEUE_SIZE; i++)
  211      Mouse_Queue[i].type = 0;
  212    Mouse_Queue_Hint = 0;
  213 }
  214 
  215 /*}}}*/
  216 
  217 static int window_exists (Window_Type *win) /*{{{*/
  218 {
  219    Window_Type *w;
  220    
  221    w = JWindow;
  222    do
  223      {
  224     if (w == win) return 1;
  225     w = w->next;
  226      }
  227    while (w != JWindow);
  228    return 0;
  229 }
  230 
  231 /*}}}*/
  232 
  233 static int switch_to_event_window (int x, int y, int *linep, int *colp, int *status) /*{{{*/
  234 {
  235    Window_Type *w;
  236    int delta_y;
  237    static int last_status;
  238    
  239    *status = 0;
  240    
  241    if (Use_This_Window != NULL)
  242      {
  243 #if JED_HAS_MENUS
  244     if (Use_This_Window == Non_Existent_Menu_Window)
  245       {
  246          *status = last_status = MENU_BAR_STATUS;
  247          *colp = x;
  248          *linep = y;
  249          return 0;
  250       }
  251 #endif
  252     if (0 == window_exists (Use_This_Window))
  253       {
  254          last_status = 0;
  255          return -1;
  256       }
  257     *status = last_status;
  258      }
  259    else
  260      {
  261 #if JED_HAS_MENUS
  262     if (Jed_Menus_Active
  263         || ((y == 1) && (Top_Window_SY != 0)))
  264       {
  265          Use_This_Window = Non_Existent_Menu_Window;
  266          *colp = x;
  267          *linep = y;
  268          *status = last_status = MENU_BAR_STATUS;
  269          return 0;
  270       }
  271 #endif       
  272     w = JWindow;
  273     do
  274       {
  275          int sy, bot;
  276 
  277          sy = w->sy;
  278          bot = sy + w->rows + 1;
  279          
  280          if ((y >= sy) && (y < bot))
  281            {
  282           Use_This_Window = w;
  283           break;
  284            }
  285          if (y == bot)
  286            {
  287           Use_This_Window = w;
  288           *status = BUFFER_STATUS_LINE;
  289           break;
  290            }
  291          w = w->next;
  292       }
  293     while (w != JWindow);
  294      }
  295    
  296    if (Use_This_Window == NULL) 
  297      {
  298     last_status = 0;
  299     return -1;
  300      }
  301    
  302    while (JWindow != Use_This_Window)
  303      other_window ();
  304 
  305    last_status = *status;
  306    if (last_status) 
  307      {
  308     *colp = x;
  309     return 0;
  310      }
  311    
  312    /* What line does y correspond ??? */
  313    delta_y = y - (Use_This_Window->sy + window_line ());
  314    y = LineNum;
  315 #if JED_HAS_LINE_ATTRIBUTES
  316    if (delta_y == 0)
  317      {
  318     Line *l = CLine;
  319     while ((l != NULL) 
  320            && (l->flags & JED_LINE_HIDDEN))
  321       {
  322          y--;
  323          l = l->prev;
  324       }
  325      }
  326    else if (delta_y > 0)
  327      {
  328     Line *l = CLine;
  329     while (delta_y && (l != NULL))
  330       {
  331          if (0 == (l->flags & JED_LINE_HIDDEN))
  332            delta_y--;
  333          l = l->next;
  334          y++;
  335       }
  336     
  337     while ((l != NULL) && (l->flags & JED_LINE_HIDDEN))
  338       {
  339          l = l->next;
  340          y++;
  341       }
  342      }
  343    else if (delta_y < 0)
  344      {
  345     Line *l = CLine;
  346     while (delta_y && (l != NULL))
  347       {
  348          if (0 == (l->flags & JED_LINE_HIDDEN))
  349            delta_y++;
  350          l = l->prev;
  351          y--;
  352       }
  353     
  354     while ((l != NULL) && (l->flags & JED_LINE_HIDDEN))
  355       {
  356          l = l->prev;
  357          y--;
  358       }
  359      }
  360 #endif
  361 
  362    *linep = y + delta_y;
  363    *colp = JWindow->hscroll_column + x - 1;
  364    return 0;
  365 }
  366 
  367 /*}}}*/
  368 
  369 static int do_function (SLang_Name_Type *fun, int line, int col, int button, int shift) /*{{{*/
  370 {
  371    int ret;
  372 
  373    if ((-1 == SLang_start_arg_list ())
  374        || (-1 == SLang_push_integer (line))
  375        || (-1 == SLang_push_integer (col))
  376        || (-1 == SLang_push_integer (button))
  377        || (-1 == SLang_push_integer (shift))
  378        || (-1 == SLang_end_arg_list ()))
  379      return 1;
  380    
  381    if ((-1 == SLexecute_function (fun))
  382        || (-1 == SLang_pop_integer (&ret)))
  383      ret = 1;
  384    
  385    return ret;
  386 }
  387 
  388 /*}}}*/
  389 
  390 static void switch_to_window (Window_Type *w) /*{{{*/
  391 {
  392    if (window_exists (w))
  393      {
  394     while (JWindow != w) other_window ();
  395      }
  396 }
  397 
  398 /*}}}*/
  399    
  400 static int do_mouse_cmd (JMouse_Type *jmouse, unsigned int type) /*{{{*/
  401 {
  402    int button, shift;
  403    int linenum = -1, column, is_status;
  404    int ret;
  405    SLang_Name_Type *fun, *default_fun;
  406    Jed_Buffer_Hook_Type *h = CBuf->buffer_hooks;
  407 
  408    button = jmouse->button;
  409    
  410    /* Consistency check */
  411    if (type == JMOUSE_DOWN)
  412      {
  413     if (Down_Mask & button)
  414       {
  415          Down_Mask = 0;
  416          return 0;
  417       }
  418     Save_Window = JWindow;
  419      }
  420    else if ((0 == (Down_Mask & button))
  421         && (type != JMOUSE_DOUBLE_CLICK)
  422         && (type != JMOUSE_TRIPLE_CLICK))
  423      {
  424     Down_Mask = 0;
  425     return 0;
  426      }
  427      
  428    if (Down_Mask == 0)
  429      Use_This_Window = NULL;
  430    
  431    if (-1 == switch_to_event_window (jmouse->x, jmouse->y, 
  432                      &linenum, &column, &is_status))
  433      {
  434     Down_Mask = 0;
  435     Use_This_Window = NULL;
  436     return 0;
  437      }
  438    
  439    default_fun = NULL;
  440    fun = NULL;
  441 
  442    switch (type)
  443      {
  444       case JMOUSE_DRAG:
  445     if (is_status) fun = Jed_Mouse_Status_Drag_Hook;
  446     else
  447       {
  448          if (h != NULL) fun = h->mouse_drag_hook;
  449          default_fun = Jed_Default_Mouse_Drag_Hook;
  450       }
  451     break;
  452 #if JED_HAS_MULTICLICK
  453       case JMOUSE_DOUBLE_CLICK:
  454     if (is_status) fun = Jed_Mouse_Status_2Click_Hook;
  455     else
  456       {
  457          if (h != NULL) fun = h->mouse_2click_hook;
  458          default_fun = Jed_Default_Mouse_2Click_Hook;
  459       }
  460     break;
  461 
  462       case JMOUSE_TRIPLE_CLICK:
  463     if (is_status) fun = Jed_Mouse_Status_3Click_Hook;
  464     else
  465       {
  466          if (h != NULL) fun = h->mouse_3click_hook;
  467          default_fun = Jed_Default_Mouse_3Click_Hook;
  468       }
  469     break;
  470 #endif
  471       case JMOUSE_DOWN:
  472     Down_Mask |= button;
  473     if (is_status) fun = Jed_Mouse_Status_Down_Hook;
  474     else
  475       {
  476          if (h != NULL) fun = h->mouse_down_hook;
  477          default_fun = Jed_Default_Mouse_Down_Hook;
  478       }
  479     break;
  480     
  481       case JMOUSE_UP:
  482     Down_Mask &= ~button;
  483     
  484     if (is_status) fun = Jed_Mouse_Status_Up_Hook;
  485     else
  486       {
  487          if (h != NULL) fun = h->mouse_up_hook;
  488          default_fun = Jed_Default_Mouse_Up_Hook;
  489       }
  490     break;
  491     
  492       default:
  493     flush_input ();
  494     fun = NULL;
  495      }
  496 
  497    if (jmouse->state & JMOUSE_SHIFT)
  498      shift = 1;
  499    else if (jmouse->state & JMOUSE_CTRL)
  500      shift = 2;
  501    else shift = 0;
  502 
  503 #if JED_HAS_MENUS
  504    if (is_status == MENU_BAR_STATUS)
  505      return jed_menu_handle_mouse (type, column, linenum, button, shift);
  506 #endif
  507 
  508    ret = -1;
  509    if (fun != NULL)
  510      {
  511     ret = do_function (fun, linenum, column, button, shift);
  512      }
  513    
  514    if ((ret == -1) && (default_fun != NULL))
  515      {
  516     ret = do_function (default_fun, linenum, column, button, shift);
  517      }
  518 
  519    if ((type == JMOUSE_UP)
  520        && (Down_Mask == 0)
  521        && (ret <= 0))
  522      {
  523     switch_to_window (Save_Window);
  524     Save_Window = NULL;
  525      }
  526 
  527    return ret;
  528 }
  529 
  530 /*}}}*/
  531 
  532 int jed_mouse_cmd (void) /*{{{*/
  533 {
  534    unsigned int type;
  535    JMouse_Type *jmouse;
  536    
  537    if ((NULL == (jmouse = get_mouse_event (&type)))
  538        || (type == JMOUSE_IGNORE_EVENT))
  539      return 0;
  540    
  541    Current_Event = *jmouse;
  542 
  543 #if JED_HAS_MULTICLICK
  544    if ((-1 == do_mouse_cmd (jmouse, type))
  545        && ((type == JMOUSE_DOUBLE_CLICK) || (type == JMOUSE_TRIPLE_CLICK)))
  546      {
  547     /* Event multiclick event not handled so simulated click. */
  548     (void) do_mouse_cmd (&Current_Event, JMOUSE_DOWN);
  549     (void) do_mouse_cmd (&Current_Event, JMOUSE_UP);
  550      }
  551 #else
  552    (void) do_mouse_cmd (jmouse, type);
  553 #endif
  554    return 1;
  555 }
  556 
  557 /*}}}*/
  558 
  559 void jed_set_current_mouse_window (void) /*{{{*/
  560 {
  561    switch_to_window (Save_Window);
  562 }
  563 
  564 /*}}}*/
  565 
  566 void jed_set_default_mouse_hook (char *hook_name, char *function) /*{{{*/
  567 {
  568    SLang_Name_Type *f;
  569    
  570    f = SLang_get_function (function);
  571 
  572    if (!strcmp ("mouse_drag", hook_name))
  573      Jed_Default_Mouse_Drag_Hook = f;
  574    else if (!strcmp ("mouse_up", hook_name))
  575      Jed_Default_Mouse_Up_Hook = f;
  576    else if (!strcmp ("mouse_down", hook_name))
  577      Jed_Default_Mouse_Down_Hook = f;
  578    else if (!strcmp ("mouse_status_up", hook_name))
  579      Jed_Mouse_Status_Up_Hook = f;
  580    else if (!strcmp ("mouse_status_down", hook_name))
  581      Jed_Mouse_Status_Down_Hook = f;
  582    else if (!strcmp ("mouse_status_drag", hook_name))
  583      Jed_Mouse_Status_Drag_Hook = f;
  584    else if (!strcmp ("mouse_status_drag", hook_name))
  585      Jed_Mouse_Status_Drag_Hook = f;
  586 #if JED_HAS_MULTICLICK
  587    else if (!strcmp ("mouse_2click", hook_name))
  588      Jed_Default_Mouse_2Click_Hook = f;
  589    else if (!strcmp ("mouse_3click", hook_name))
  590      Jed_Default_Mouse_3Click_Hook = f;
  591 #endif
  592 }
  593 
  594 /*}}}*/
  595 
  596 #endif                     /* HAS_MOUSE */