unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alin Soare <as1789@gmail.com>
To: Emacs Dev <emacs-devel@gnu.org>
Subject: Re: Tabs for console.
Date: Sat, 4 Dec 2010 23:42:24 +0200	[thread overview]
Message-ID: <AANLkTi=cPSZpFuxx4xP6FtCd0n6Q17SkG-gcH8N4XQYO@mail.gmail.com> (raw)
In-Reply-To: <m262vb3uqh.fsf@tapoueh.org>


[-- Attachment #1.1: Type: text/plain, Size: 400 bytes --]

This is a version in which I added an environment for every tab. For now,
there is no reason to make the environment an obarray, but this will be
required if others want to write scripts that give other definitions for a
tab, but for window configurations. For me, it is enough to know that only
the tab:init function changes that environment, and I find the winconfig
variable on the cadr position.

[-- Attachment #1.2: Type: text/html, Size: 423 bytes --]

[-- Attachment #2: 0001-tabs-for-console-tabs-as-window-configuration.patch --]
[-- Type: text/x-patch, Size: 19720 bytes --]

From e369ad3fc8c95e81e0d84758896297cf970b324a Mon Sep 17 00:00:00 2001
From: root <root@alin.(none)>
Date: Thu, 2 Dec 2010 23:53:41 +0200
Subject: [PATCH] tabs for console - tabs as window configuration

---
 src/dispextern.h |    3 +
 src/frame.c      |  240 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/frame.h      |   31 ++++++-
 src/window.c     |    5 +
 src/xdisp.c      |   79 ++++++++++++++++++
 src/xfaces.c     |   10 ++
 6 files changed, 359 insertions(+), 9 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 7426c03..2a87044 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1697,6 +1697,9 @@ enum face_id
   MOUSE_FACE_ID,
   MENU_FACE_ID,
   VERTICAL_BORDER_FACE_ID,
+  CURRENT_TAB_FACE_ID,
+  ODD_TAB_FACE_ID,
+  EVEN_TAB_FACE_ID,
   BASIC_FACE_ID_SENTINEL
 };
 
diff --git a/src/frame.c b/src/frame.c
index ba675be..b90bff3 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -118,16 +118,20 @@ Lisp_Object Qwindow_id;
 Lisp_Object Qouter_window_id;
 #endif
 Lisp_Object Qparent_id;
-Lisp_Object Qtitle, Qname;
+Lisp_Object Qtitle, Qname, Qtab_name, Qtab, Qcurrent_tab;
+Lisp_Object Qtab_env;
+Lisp_Object Qtab_list;
 Lisp_Object Qexplicit_name;
 Lisp_Object Qunsplittable;
-Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
+Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position, Qtab_bar_lines;
 Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
 Lisp_Object Qleft_fringe, Qright_fringe;
 Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 
+Lisp_Object Qtab_activate, Qtab_deactivate, Qtab_init;
+
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
 Lisp_Object Qsticky;
 Lisp_Object Qfont_backend;
@@ -197,6 +201,149 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
       adjust_glyphs (f);
     }
 }
+
+/* this is identical to set_menu_bar_lines_1 */
+static void
+set_tab_bar_lines_1 ( Lisp_Object window, int n)
+{
+  struct window *w = XWINDOW (window);
+
+  XSETFASTINT (w->last_modified, 0);
+  XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
+  XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
+
+  if (INTEGERP (w->orig_top_line))
+    XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
+  if (INTEGERP (w->orig_total_lines))
+    XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
+
+  /* Handle just the top child in a vertical split.  */
+  if (!NILP (w->vchild))
+    set_tab_bar_lines_1 (w->vchild, n);
+
+  /* Adjust all children in a horizontal split.  */
+  for (window = w->hchild; !NILP (window); window = w->next)
+    {
+      w = XWINDOW (window);
+      set_tab_bar_lines_1 (window, n);
+    }
+}
+
+static void
+set_tab_bar_lines (struct frame *f, Lisp_Object value)
+{
+    int nlines, olines, maxlines;
+    Lisp_Object frame;
+
+    if (FRAME_MINIBUF_ONLY_P (f))
+	return;
+
+    XSETFRAME(frame, f);
+
+    if (INTEGERP (value))
+	nlines = XINT (value);
+    else
+	nlines = 0;
+
+    struct frame *this;
+    this = XFRAME(frame);
+    olines = FRAME_TAB_BAR_LINES (this);
+    if (nlines != olines)
+    {
+	if (EQ (frame, selected_frame))
+            /* redisplay is required only when one changes the
+               selected tab */
+            windows_or_buffers_changed++;
+	FRAME_WINDOW_SIZES_CHANGED (this) = 1;
+	FRAME_TAB_BAR_LINES (this) = nlines;
+	set_tab_bar_lines_1 (this->root_window, nlines - olines);
+	adjust_glyphs (this);
+    }
+
+}
+
+void
+activate_tab (struct frame *f, int tab_index)
+{
+    Lisp_Object activatecode, tab;
+    FRAME_CURRENT_TAB (f) = XINT (tab_index);
+    tab = Fnth ( tab_index, f -> tab_bar_items ) ;
+    activatecode = Fassq (Qtab_activate, tab);
+    if (! EQ (Qnil, activatecode))
+    {
+	activatecode = XCDR (activatecode);
+	return (void) Ffuncall (1, &activatecode);
+    }
+}
+
+void
+deactivate_tab (struct frame *f)
+{
+    return;
+    Lisp_Object deactivatecode, tab;
+    tab = AREF ( f->tab_bar_items, f->current_tab ) ;
+    deactivatecode = Fassq (Qtab_deactivate, tab);
+    if (! EQ (Qnil, deactivatecode))
+    {
+	deactivatecode = XCDR (deactivatecode);
+	return (void) Ffuncall (1, &deactivatecode);
+    }
+}
+
+void
+set_current_tab (struct frame *f, Lisp_Object value)
+{
+    int otab, tab;
+
+    if (FRAME_MINIBUF_ONLY_P (f))
+	return;
+
+    Lisp_Object frame;
+    XSETFRAME(frame, f);
+
+    if (INTEGERP (value))
+	tab = XINT (value);
+    else
+	return (void) deactivate_tab (f);
+
+    otab = FRAME_CURRENT_TAB (f);
+
+    /* no tag is active */
+    if (Flength (FRAME_TAB_BAR_ITEMS (f)) <= value)
+	return (void) deactivate_tab (f);
+    
+    if (tab != otab)
+    {
+	if (EQ (frame, selected_frame))
+            /* redisplay is required only when one changes the
+               selected tab */
+            windows_or_buffers_changed++;
+	FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+	deactivate_tab (f);
+	activate_tab (f, value);
+	adjust_glyphs (f);
+    }
+
+}
+
+void
+add_tab_environment (struct frame *f,
+		     Lisp_Object prop)
+{
+    Lisp_Object env, l;
+    l = Fnth (make_number (f->current_tab), f->tab_bar_items);
+    if (NILP(prop))
+	return;
+    return;
+    env = Fcons (prop,
+		 XCDR (Fassq (Qtab_env,
+			      XCDR ( AREF (f->tab_bar_items, f->current_tab)))));
+//    env = Fcons (Qtab_env, Fcons ( prop, XCDR (env) ) );
+    store_in_alist (&l, Qtab_env, env);
+    
+}
+
+
 \f
 Lisp_Object Vframe_list;
 
@@ -348,6 +495,10 @@ make_frame (int mini_p)
   f->font_driver_list = NULL;
   f->font_data_list = NULL;
 
+  f->tab_bar_items = Qnil;
+  f->current_tab = 0;
+  f->last_tab = 0;
+
   root_window = make_window ();
   if (mini_p)
     {
@@ -570,7 +721,6 @@ make_initial_frame (void)
   return f;
 }
 
-
 struct frame *
 make_terminal_frame (struct terminal *terminal)
 {
@@ -650,6 +800,44 @@ get_future_frame_param (Lisp_Object parameter,
   return result;
 }
 
+Lisp_Object
+add_tab (Lisp_Object parms)
+{
+    Lisp_Object tab_name, initcode, activatecode, deactivatecode, tab, env, name;
+    
+    Lisp_Object tab_object[4];
+
+  struct frame *sf = SELECTED_FRAME ();
+  if (sf->last_tab == 1000)
+    return Qnil;
+
+  activatecode = Fassq (Qtab_activate, parms);
+  deactivatecode = Fassq (Qtab_deactivate, parms);
+  env = Fassq (Qtab_env, parms);
+  name = Fassq (Qtab_name, parms);
+  
+  name = NILP (name) ? make_string (" tab", 4) : XCDR (name);
+
+  tab_name = Fcons (Qtab_name, name);
+  tab_object[0] = NILP (tab_name) ? Qnil:Fcons (tab_name, Qnil);
+  tab_object[1] = NILP (activatecode) ? Qnil: Fcons (activatecode, Qnil);
+  tab_object[2] = NILP (deactivatecode) ? Qnil:Fcons (deactivatecode, Qnil);
+  tab_object[3] = NILP (env) ? Qnil:Fcons (env, Qnil);
+  tab = Fappend ( 4, tab_object );
+
+  /* ASET (sf->tab_bar_items, sf->last_tab++, tab); */
+  Lisp_Object new[2];
+  new[0] = sf->tab_bar_items;
+  new[1] = Fcons (tab, Qnil);
+
+  sf->tab_bar_items = Fappend ( 2,  new);
+
+  initcode = Fassq (Qtab_init, parms);
+
+  /* sf->last_tab++; */
+  return make_number (sf->last_tab++);
+}
+
 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
        1, 1, 0,
        doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -674,6 +862,13 @@ affects all frames on the same terminal device.  */)
   Lisp_Object frame, tem;
   struct frame *sf = SELECTED_FRAME ();
 
+  Lisp_Object tab;
+
+  tab = Fassq (Qtab, parms);
+  if (! EQ (Qnil, tab))
+      return add_tab (parms);
+
+
 #ifdef MSDOS
   if (sf->output_method != output_msdos_raw
       && sf->output_method != output_termcap)
@@ -2286,9 +2481,15 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
   if (! FRAME_WINDOW_P (f))
     {
       if (EQ (prop, Qmenu_bar_lines))
-	set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+	  set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
+      else if (EQ (prop, Qtab_bar_lines))
+	  set_tab_bar_lines (f, val);
       else if (EQ (prop, Qname))
 	set_term_frame_name (f, val);
+      else if (EQ (prop, Qcurrent_tab))
+      	set_current_tab (f, val);
+      else if (EQ (prop, Qtab_env))
+      	add_tab_environment (f, val);
     }
 
   if (EQ (prop, Qminibuffer) && WINDOWP (val))
@@ -2394,11 +2595,19 @@ If FRAME is omitted, return information on the currently selected frame.  */)
 #endif
     {
       /* This ought to be correct in f->param_alist for an X frame.  */
-      Lisp_Object lines;
+	Lisp_Object lines, tabenv;
       XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
       store_in_alist (&alist, Qmenu_bar_lines, lines);
+      XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
+      store_in_alist (&alist, Qtab_bar_lines, lines);
+      XSETFASTINT (lines, FRAME_CURRENT_TAB (f));
+      store_in_alist (&alist, Qcurrent_tab, lines);
+      tabenv= Fcdr ( Fassq (Qtab_env,
+			    Fnth (make_number (f->current_tab), f->tab_bar_items)));
+      store_in_alist (&alist, Qtab_env, tabenv);
+      /* provide an informal reference to tabs. */
+      store_in_alist (&alist, Qtab_list, f->tab_bar_items);
     }
-
   UNGCPRO;
   return alist;
 }
@@ -2822,6 +3031,9 @@ static const struct frame_parm_table frame_parms[] =
   {"icon-type",			&Qicon_type},
   {"internal-border-width",	&Qinternal_border_width},
   {"menu-bar-lines",		&Qmenu_bar_lines},
+  {"tab-bar-lines",		&Qtab_bar_lines},
+  {"current-tab",		&Qcurrent_tab},
+  {"tab-list",                  &Qtab_list},
   {"mouse-color",		&Qmouse_color},
   {"name",			&Qname},
   {"scroll-bar-width",		&Qscroll_bar_width},
@@ -4443,6 +4655,22 @@ syms_of_frame (void)
   Qterminal_live_p = intern_c_string ("terminal-live-p");
   staticpro (&Qterminal_live_p);
 
+  Qtab = intern_c_string ("tab");
+  staticpro (&Qtab);
+
+  Qtab_env = intern_c_string ("tab:env");
+  staticpro (&Qtab_env);
+
+  Qtab_name = intern_c_string ("tab:name");
+  staticpro (&Qtab_name);
+
+  Qtab_activate = intern_c_string ("tab:activate");
+  staticpro (&Qtab_activate);
+  Qtab_deactivate = intern_c_string ("tab:deactivate");
+  staticpro (&Qtab_deactivate);
+  Qtab_init = intern_c_string ("tab:init");
+  staticpro (&Qtab_init);
+
 #ifdef HAVE_NS
   Qns_parse_geometry = intern_c_string ("ns-parse-geometry");
   staticpro (&Qns_parse_geometry);
diff --git a/src/frame.h b/src/frame.h
index 31f6017..3110fd4 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -171,6 +171,12 @@ struct frame
      Only the X toolkit version uses this.  */
   Lisp_Object menu_bar_vector;
 
+    /*
+     * a list with conses of the form ("string_tab_name" . (alist_tab_parameters))
+     */
+    Lisp_Object tab_bar_items;
+
+
   /* Predicate for selecting buffers for other-buffer.  */
   Lisp_Object buffer_predicate;
 
@@ -203,6 +209,13 @@ struct frame
   /* Cache of realized faces.  */
   struct face_cache *face_cache;
 
+    /*
+      the index of the last activated tab.
+     */
+    int current_tab;
+
+    int last_tab;
+
   /* Number of elements in `menu_bar_vector' that have meaningful data.  */
   EMACS_INT menu_bar_items_used;
 
@@ -360,6 +373,8 @@ struct frame
   /* Number of lines of menu bar.  */
   int menu_bar_lines;
 
+    int tab_bar_lines;
+
 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
     || defined (HAVE_NS) || defined (USE_GTK)
   /* Nonzero means using a menu bar that comes from the X toolkit.  */
@@ -590,6 +605,11 @@ typedef struct frame *FRAME_PTR;
    These lines are counted in FRAME_LINES.  */
 #define FRAME_MENU_BAR_LINES(f) (f)->menu_bar_lines
 
+#define FRAME_CURRENT_TAB(f) f -> current_tab
+#define FRAME_TAB_BAR_ITEMS(f) f -> tab_bar_items
+#define FRAME_TAB_BAR_LINES(f) f -> tab_bar_lines
+
+
 /* Nonzero if this frame should display a tool bar
    in a way that does not use any text lines.  */
 #if defined (USE_GTK) || defined (HAVE_NS)
@@ -606,7 +626,7 @@ typedef struct frame *FRAME_PTR;
 /* Lines above the top-most window in frame F.  */
 
 #define FRAME_TOP_MARGIN(F) \
-     (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F))
+     (FRAME_MENU_BAR_LINES (F) + FRAME_TOOL_BAR_LINES (F) + FRAME_TAB_BAR_LINES(F))
 
 /* Pixel height of the top margin above.  */
 
@@ -832,13 +852,18 @@ typedef struct frame *FRAME_PTR;
    supported.  An alternate definition of the macro would expand to
    something which executes the statement once.  */
 
+#define FOR_EACH_TAB(frame, list_var, tab_var)			\
+    for ((list_var) = frame->tab_bar_items;			\
+	 (CONSP (list_var)					\
+	  && (tab_var = XCAR (list_var), 1));			\
+	 list_var = XCDR (list_var))
+
 #define FOR_EACH_FRAME(list_var, frame_var)			\
   for ((list_var) = Vframe_list;				\
        (CONSP (list_var)					\
-	&& (frame_var = XCAR (list_var), 1));		\
+	&& (frame_var = XCAR (list_var), 1));			\
        list_var = XCDR (list_var))
 
-
 extern Lisp_Object Qframep, Qframe_live_p;
 extern Lisp_Object Qtty, Qtty_type;
 extern Lisp_Object Qtty_color_mode;
diff --git a/src/window.c b/src/window.c
index a2a0c79..7096488 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5832,6 +5832,7 @@ struct save_window_data
 
     int frame_cols, frame_lines, frame_menu_bar_lines;
     int frame_tool_bar_lines;
+    int frame_tab_bar_lines;
   };
 
 /* This is saved as a Lisp_Vector  */
@@ -5963,6 +5964,7 @@ the return value is nil.  Otherwise the value is t.  */)
       int previous_frame_cols =  FRAME_COLS  (f);
       int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
       int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
+      int previous_frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f);
 
       /* The mouse highlighting code could get screwed up
 	 if it runs during this.  */
@@ -6414,6 +6416,7 @@ redirection (see `redirect-frame-focus').  */)
   data->frame_lines = FRAME_LINES (f);
   data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
   data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
+  data->frame_tab_bar_lines = FRAME_TAB_BAR_LINES (f);
   data->selected_frame = selected_frame;
   data->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (data->current_buffer, current_buffer);
@@ -6910,6 +6913,8 @@ compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positi
     return 0;
   if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
     return 0;
+  if (d1->frame_tab_bar_lines != d2->frame_tab_bar_lines)
+    return 0;
   if (! EQ (d1->selected_frame, d2->selected_frame))
     return 0;
   /* Don't compare the current_window field directly.
diff --git a/src/xdisp.c b/src/xdisp.c
index 77e9db2..bbd8bd3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -330,6 +330,8 @@ Lisp_Object Qinhibit_eval_during_redisplay;
 Lisp_Object Qbuffer_position, Qposition, Qobject;
 Lisp_Object Qright_to_left, Qleft_to_right;
 
+Lisp_Object Qtab_name;
+
 /* Cursor shapes */
 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
 
@@ -1059,6 +1061,8 @@ static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lis
 static const char *decode_mode_spec (struct window *, int, int, int,
 				     Lisp_Object *);
 static void display_menu_bar (struct window *);
+static void display_tab_bar (struct window *w);
+
 static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
 				EMACS_INT *);
 static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
@@ -14575,6 +14579,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       && EQ (FRAME_SELECTED_WINDOW (f), window))
     {
       int redisplay_menu_p = 0;
+      int redisplay_tab_p = 0;
       int redisplay_tool_bar_p = 0;
 
       if (FRAME_WINDOW_P (f))
@@ -14589,9 +14594,14 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
       else
         redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
 
+      redisplay_tab_p = FRAME_TAB_BAR_LINES (f) > 0;
+
       if (redisplay_menu_p)
         display_menu_bar (w);
 
+      if (redisplay_tab_p)
+	  display_tab_bar (w);
+
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (f))
         {
@@ -18176,6 +18186,75 @@ See also `bidi-paragraph-direction'.  */)
     }
 }
 
+void
+display_tab_bar (struct window *w)
+{
+    const int tab_length = 10;
+
+    struct frame *fr = XFRAME (WINDOW_FRAME (w));
+
+    struct it it;
+    int index;
+    init_iterator (&it, w, -1, -1,
+		   fr->desired_matrix->rows + FRAME_MENU_BAR_LINES (fr),
+		   DEFAULT_FACE_ID);
+    it.first_visible_x = 0;
+    it.last_visible_x = FRAME_COLS (fr);
+
+  /* Clear all rows of the menu bar.  */
+  for (index = 0;
+       index < FRAME_TAB_BAR_LINES (fr);
+       ++index)
+    {
+      struct glyph_row *row = it.glyph_row + index;
+      clear_glyph_row (row);
+      row->enabled_p = 1;
+      row->full_width_p = 1;
+    }
+
+  int ii=0, oddrow=0, oddcol=0;
+  Lisp_Object tab, tab_list, s;
+  FOR_EACH_TAB (fr, tab_list, tab)
+  {
+      Lisp_Object tabname = Fcdr (Fassq (Qtab_name, tab));
+      if (it. hpos + tab_length > FRAME_COLS (fr))
+      {
+	  /* Fill out the line with spaces.  */
+	  it.base_face_id = DEFAULT_FACE_ID;
+	  while (it.current_x < it.last_visible_x)
+	      display_string (" ", Qnil, Qnil, 0, 0,  &it, 1, 0, 0, -1);
+
+  	  if (unix == (it.current_y + 1))
+	      oddcol = ii % 2;
+
+	  oddrow = (oddcol)? (ii%2) : !oddrow;
+
+      	  it.hpos = it.current_x = 0;
+	  it.current_y ++;
+      	  ++it.vpos;
+      	  it.glyph_row++;
+	  if (it.current_y > FRAME_TAB_BAR_LINES (fr))
+      	      break;
+      }
+
+      it.base_face_id = (ii == FRAME_CURRENT_TAB (fr)) ? CURRENT_TAB_FACE_ID :
+      	   oddrow ? ODD_TAB_FACE_ID :
+      	  EVEN_TAB_FACE_ID;
+      
+      int len = SCHARS (tabname) > tab_length ? tab_length: SCHARS (tabname);
+      s = Fsubstring (tabname, make_number(0), make_number (len));
+      display_string (NULL, s, Qnil, 0, 0, &it, tab_length, 0, 0, -1);
+
+      oddrow = ! oddrow;
+      ii++;
+  }
+
+  
+  /* Compute the total height of the lines.  */
+  compute_line_metrics (&it);
+
+}
+
 
 \f
 /***********************************************************************
diff --git a/src/xfaces.c b/src/xfaces.c
index 5c7cfe6..3e14a64 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -348,6 +348,7 @@ Lisp_Object Qframe_set_background_mode;
 Lisp_Object Qdefault, Qtool_bar, Qregion, Qfringe;
 Lisp_Object Qheader_line, Qscroll_bar, Qcursor, Qborder, Qmouse, Qmenu;
 Lisp_Object Qmode_line_inactive, Qvertical_border;
+Lisp_Object Qodd_tab_face, Qeven_tab_face, Qcurrent_tab_face;
 
 /* The symbol `face-alias'.  A symbols having that property is an
    alias for another face.  Value of the property is the name of
@@ -5389,6 +5390,9 @@ realize_basic_faces (struct frame *f)
       realize_named_face (f, Qmouse, MOUSE_FACE_ID);
       realize_named_face (f, Qmenu, MENU_FACE_ID);
       realize_named_face (f, Qvertical_border, VERTICAL_BORDER_FACE_ID);
+      realize_named_face (f, Qcurrent_tab_face, CURRENT_TAB_FACE_ID);
+      realize_named_face (f, Qodd_tab_face, ODD_TAB_FACE_ID);
+      realize_named_face (f, Qeven_tab_face, EVEN_TAB_FACE_ID);
 
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
@@ -6659,6 +6663,12 @@ syms_of_xfaces (void)
   staticpro (&Qmode_line_inactive);
   Qvertical_border = intern_c_string ("vertical-border");
   staticpro (&Qvertical_border);
+  Qcurrent_tab_face = intern ("current-tab-face");
+  staticpro (&Qcurrent_tab_face);
+  Qodd_tab_face = intern ("odd-tab-face");
+  staticpro (&Qodd_tab_face);
+  Qeven_tab_face = intern ("even-tab-face");
+  staticpro (&Qeven_tab_face);
   Qtty_color_desc = intern_c_string ("tty-color-desc");
   staticpro (&Qtty_color_desc);
   Qtty_color_standard_values = intern_c_string ("tty-color-standard-values");
-- 
1.7.1


[-- Attachment #3: test-tabs.el --]
[-- Type: text/x-emacs-lisp, Size: 2221 bytes --]


;; evaluate this file, sexp after sexp, and follow the comments.

;; set a minimal environment
(progn
  (custom-set-faces
   '(current-tab-face ((t ( :inherit 'default-face  :foreground "lightblue" :bold t :underline t))))
   '(odd-tab-face    ((t ( :background "red"    :foreground "white" ))))
   '(even-tab-face   ((t ( :background "green"  :foreground "black")))))
  (set-frame-parameter (selected-frame) 'tab-bar-lines 4)
  (set-frame-parameter (selected-frame) 'menu-bar-lines 0))

;; this is a definition of a tab as a window configuration
(defun make-wc-tab (parms)
  ;; save curent win config
  (setq sym (make-symbol "winconfig"))
  (set sym  (current-window-configuration))
  ;; make a tab that keeps a window configuration. When it is created,
  ;; it memories the current win config. When it is activated, it
  ;; restores the memorized win config
  (make-terminal-frame
   (list '(tab . t)
	 '(tab:name . "WinC")
	 '(tab:activate
	   .
	   (lambda ()
	     (set-window-configuration
	      (eval (cdr (assoc 'tab:env (frame-parameters) ) ) ) ) ) )
	 ;; save the current win config into the tab environment
	 (cons 'tab:env sym) ) ) )

;; make a first tab keeping current win config
(make-wc-tab nil)

;; alter the window configuration
((lambda nil
   (split-window-vertically)))

;; make a second tab keeping current win config
(make-wc-tab nil)

;; alter the window configuration
((lambda nil
   (split-window-horizontally)))

;; make a third tab keeping current win config
(make-wc-tab nil)

;; keep only the current window
(delete-other-windows)

;; now activate the tabs that keep the memorized win config.  this
;; function disovered a bug in window configuration . LOL.  If you
;; change the tab-bar-lines or menu-bar-lines after creating a tab
;; and before activatin it here, emacs crashes. LOL.

;; activate the second
(set-frame-parameter (selected-frame) 'current-tab 1)

;; the third
(set-frame-parameter (selected-frame) 'current-tab 2)

;; the first again
(set-frame-parameter (selected-frame) 'current-tab 0)

;; dump frame params
(progn
  (setq  eval-expression-print-length 5000
	 eval-expression-print-level  5000
	 print-level 5000
	 )
  (frame-parameters) )

;; that's all for now.





  reply	other threads:[~2010-12-04 21:42 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <AANLkTim8zuFRh2L81g9KgtDon=U5Mvr+QO+HWGE1nqXP@mail.gmail.com>
2010-10-27 16:39 ` Fwd: Tabs for console Alin Soare
2010-11-08 19:22   ` Stefan Monnier
2010-11-08 19:51     ` Alin Soare
     [not found]       ` <AANLkTim8BoGpECQUUNfPidbn2k_HP77sykR=HYqw9BOE@mail.gmail.com>
     [not found]         ` <AANLkTinPBfV8OC7d9qOBWGW6130D2nXjg+=Nv2rKqMr1@mail.gmail.com>
     [not found]           ` <jwvhbewqnjj.fsf-monnier+emacs@gnu.org>
2010-12-02 22:43             ` Alin Soare
2010-12-02 22:45               ` Alin Soare
2010-12-03  8:19                 ` martin rudalics
2010-12-03  9:37                 ` Andreas Schwab
2010-12-04 21:48                   ` Alin Soare
2010-12-03  9:52                 ` Andreas Schwab
2010-12-03 11:11                   ` Alin Soare
2010-12-03 12:29                     ` Dimitri Fontaine
2010-12-04 21:42                       ` Alin Soare [this message]
2010-12-04 21:55                       ` Alin Soare
2011-03-11  8:52       ` A Soare
     [not found]     ` <AANLkTikwua2bfyvJkt+sn2vR_CzTZA6Hs0Lw=NJSVwT4@mail.gmail.com>
     [not found]       ` <jwvd3peoig0.fsf-monnier+emacs@gnu.org>
     [not found]         ` <AANLkTikPRKbvq0mg2X1Huio1z5sF3UvF6+cpT10mH-H-@mail.gmail.com>
     [not found]           ` <jwvzksilkfd.fsf-monnier+emacs@gnu.org>
     [not found]             ` <AANLkTi=MiubmGJ_Gk9OVzHY7uc+DOkHHpj5Ht+j7uNx8@mail.gmail.com>
     [not found]               ` <jwvtyiqk2al.fsf-monnier+emacs@gnu.org>
     [not found]                 ` <AANLkTi=0g00xn2P_yKE0gGkH-ZaZSvz+8yY=yy2=-6W=@mail.gmail.com>
     [not found]                   ` <jwvsjyai7lv.fsf-monnier+emacs@gnu.org>
2010-12-07  4:47                     ` Fwd: " Alin Soare
2010-12-07  4:50                       ` Alin Soare
2010-12-07 17:06                       ` Stefan Monnier
2010-12-08  8:14                         ` Alin Soare
     [not found]                           ` <AANLkTikaXr_4bVR2_v7HVFfPB93Sw10e63cKqTRwOunS@mail.gmail.com>
2010-12-08 11:16                             ` Alin Soare
2010-12-09  4:29                           ` Fwd: " Stefan Monnier
2010-12-09  8:26                             ` Alin Soare
2010-12-10  3:35                               ` Stefan Monnier
2010-12-10  8:15                                 ` Alin Soare
2010-12-10 20:13                                   ` Stefan Monnier
2010-12-10 21:09                                     ` Alin Soare
2010-12-10 21:23                                       ` Davis Herring
2010-12-10 21:34                                         ` Alin Soare
2010-12-12 20:02                                           ` Alin Soare
2010-12-13 17:23                                             ` Stefan Monnier
2010-12-13 21:01                                               ` Alin Soare
2010-12-14 15:25                                 ` Alin Soare
2010-10-27 20:34 ` Alin Soare
2010-10-29  7:49 Alin Soare
  -- strict thread matches above, loose matches on Subject: below --
2010-12-21  1:14 Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='AANLkTi=cPSZpFuxx4xP6FtCd0n6Q17SkG-gcH8N4XQYO@mail.gmail.com' \
    --to=as1789@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).