|
|
8fa6cd |
diff -paur xchat2.orig/src/common/inbound.c xchat2/src/common/inbound.c
|
|
|
8fa6cd |
--- xchat2.orig/src/common/inbound.c 2008-07-20 17:31:44.898468115 +0200
|
|
|
8fa6cd |
+++ xchat2/src/common/inbound.c 2008-07-19 19:57:09.799906780 +0200
|
|
|
8fa6cd |
@@ -297,7 +297,10 @@ is_hilight (char *from, char *text, sess
|
|
|
8fa6cd |
{
|
|
|
8fa6cd |
g_free (text);
|
|
|
8fa6cd |
if (sess != current_tab)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
sess->nick_said = TRUE;
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
fe_set_hilight (sess);
|
|
|
8fa6cd |
return 1;
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
@@ -344,6 +347,7 @@ inbound_action (session *sess, char *cha
|
|
|
8fa6cd |
sess->msg_said = TRUE;
|
|
|
8fa6cd |
sess->new_data = FALSE;
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
user = userlist_find (sess, from);
|
|
|
8fa6cd |
@@ -395,6 +399,7 @@ inbound_chanmsg (server *serv, session *
|
|
|
8fa6cd |
{
|
|
|
8fa6cd |
sess->msg_said = TRUE;
|
|
|
8fa6cd |
sess->new_data = FALSE;
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
user = userlist_find (sess, from);
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/common/xchat.c xchat2/src/common/xchat.c
|
|
|
8fa6cd |
--- xchat2.orig/src/common/xchat.c 2008-07-20 17:31:44.900468825 +0200
|
|
|
8fa6cd |
+++ xchat2/src/common/xchat.c 2008-07-20 17:33:57.089468218 +0200
|
|
|
8fa6cd |
@@ -71,6 +71,23 @@ GSList *usermenu_list = 0;
|
|
|
8fa6cd |
GSList *urlhandler_list = 0;
|
|
|
8fa6cd |
GSList *tabmenu_list = 0;
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+/*
|
|
|
8fa6cd |
+ * This array contains 5 double linked lists, one for each priority in the
|
|
|
8fa6cd |
+ * "interesting session" queue ("channel" stands for everything but
|
|
|
8fa6cd |
+ * SESS_DIALOG):
|
|
|
8fa6cd |
+ *
|
|
|
8fa6cd |
+ * [0] queries with hilight
|
|
|
8fa6cd |
+ * [1] queries
|
|
|
8fa6cd |
+ * [2] channels with hilight
|
|
|
8fa6cd |
+ * [3] channels with dialogue
|
|
|
8fa6cd |
+ * [4] channels with other data
|
|
|
8fa6cd |
+ *
|
|
|
8fa6cd |
+ * Each time activity happens the corresponding session is put at the
|
|
|
8fa6cd |
+ * beginning of one of the lists. The aim is to be able to switch to the
|
|
|
8fa6cd |
+ * session with the most important/recent activity.
|
|
|
8fa6cd |
+ */
|
|
|
8fa6cd |
+GList *sess_list_by_lastact[5] = {NULL, NULL, NULL, NULL, NULL};
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
static int in_xchat_exit = FALSE;
|
|
|
8fa6cd |
int xchat_is_quitting = FALSE;
|
|
|
8fa6cd |
/* command-line args */
|
|
|
8fa6cd |
@@ -93,6 +110,105 @@ struct xchatprefs prefs;
|
|
|
8fa6cd |
SSL_CTX *ctx = NULL;
|
|
|
8fa6cd |
#endif
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+/*
|
|
|
8fa6cd |
+ * Update the priority queue of the "interesting sessions"
|
|
|
8fa6cd |
+ * (sess_list_by_lastact).
|
|
|
8fa6cd |
+ */
|
|
|
8fa6cd |
+void
|
|
|
8fa6cd |
+lastact_update(session *sess)
|
|
|
8fa6cd |
+{
|
|
|
8fa6cd |
+ int newidx;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* Find the priority (for the order see before) */
|
|
|
8fa6cd |
+ if (sess->type == SESS_DIALOG)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ if (sess->nick_said)
|
|
|
8fa6cd |
+ newidx = LACT_QUERY_HI;
|
|
|
8fa6cd |
+ else if (sess->msg_said)
|
|
|
8fa6cd |
+ newidx = LACT_QUERY;
|
|
|
8fa6cd |
+ else if (sess->new_data)
|
|
|
8fa6cd |
+ newidx = LACT_QUERY;
|
|
|
8fa6cd |
+ else
|
|
|
8fa6cd |
+ newidx = LACT_NONE;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+ else
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ if (sess->nick_said)
|
|
|
8fa6cd |
+ newidx = LACT_CHAN_HI;
|
|
|
8fa6cd |
+ else if (sess->msg_said)
|
|
|
8fa6cd |
+ newidx = LACT_CHAN;
|
|
|
8fa6cd |
+ else if (sess->new_data)
|
|
|
8fa6cd |
+ newidx = LACT_CHAN_DATA;
|
|
|
8fa6cd |
+ else
|
|
|
8fa6cd |
+ newidx = LACT_NONE;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* Check if this update is a no-op */
|
|
|
8fa6cd |
+ if (sess->lastact_idx == newidx &&
|
|
|
8fa6cd |
+ ((newidx != LACT_NONE && sess->lastact_elem == sess_list_by_lastact[newidx]) ||
|
|
|
8fa6cd |
+ (newidx == LACT_NONE)))
|
|
|
8fa6cd |
+ return;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* Remove from the old position (and, if no new position, return */
|
|
|
8fa6cd |
+ else if (sess->lastact_idx != LACT_NONE && sess->lastact_elem)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ sess_list_by_lastact[sess->lastact_idx] = g_list_remove_link(
|
|
|
8fa6cd |
+ sess_list_by_lastact[sess->lastact_idx],
|
|
|
8fa6cd |
+ sess->lastact_elem);
|
|
|
8fa6cd |
+ if (newidx == LACT_NONE)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ sess->lastact_idx = newidx;
|
|
|
8fa6cd |
+ return;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* No previous position, allocate new */
|
|
|
8fa6cd |
+ else if (!sess->lastact_elem)
|
|
|
8fa6cd |
+ sess->lastact_elem = g_list_prepend(sess->lastact_elem, sess);
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ sess->lastact_idx = newidx;
|
|
|
8fa6cd |
+ sess_list_by_lastact[newidx] = g_list_concat(
|
|
|
8fa6cd |
+ sess->lastact_elem, sess_list_by_lastact[newidx]);
|
|
|
8fa6cd |
+}
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+/*
|
|
|
8fa6cd |
+ * Extract the first session from the priority queue of sessions with recent
|
|
|
8fa6cd |
+ * activity. Return NULL if no such session can be found.
|
|
|
8fa6cd |
+ *
|
|
|
8fa6cd |
+ * If filter is specified, skip a session if filter(session) returns 0. This
|
|
|
8fa6cd |
+ * can be used for UI-specific needs, e.g. in fe-gtk we want to filter out
|
|
|
8fa6cd |
+ * detached sessions.
|
|
|
8fa6cd |
+ */
|
|
|
8fa6cd |
+session *
|
|
|
8fa6cd |
+lastact_getfirst(int (*filter) (session *sess))
|
|
|
8fa6cd |
+{
|
|
|
8fa6cd |
+ int i;
|
|
|
8fa6cd |
+ session *sess = NULL;
|
|
|
8fa6cd |
+ GList *curitem;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* 5 is the number of priority classes LACT_ */
|
|
|
8fa6cd |
+ for (i = 0; i < 5 && !sess; i++)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ curitem = sess_list_by_lastact[i];
|
|
|
8fa6cd |
+ while (curitem && !sess)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ sess = g_list_nth_data(curitem, 0);
|
|
|
8fa6cd |
+ if (!sess || (filter && !filter(sess)))
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ sess = NULL;
|
|
|
8fa6cd |
+ curitem = g_list_next(curitem);
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ if (sess)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ sess_list_by_lastact[i] = g_list_remove_link(sess_list_by_lastact[i], curitem);
|
|
|
8fa6cd |
+ sess->lastact_idx = LACT_NONE;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ return sess;
|
|
|
8fa6cd |
+}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
int
|
|
|
8fa6cd |
is_session (session * sess)
|
|
|
8fa6cd |
@@ -362,6 +478,9 @@ session_new (server *serv, char *from, i
|
|
|
8fa6cd |
|
|
|
8fa6cd |
sess_list = g_slist_prepend (sess_list, sess);
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+ sess->lastact_elem = NULL;
|
|
|
8fa6cd |
+ sess->lastact_idx = LACT_NONE;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
fe_new_window (sess, focus);
|
|
|
8fa6cd |
|
|
|
8fa6cd |
return sess;
|
|
|
8fa6cd |
@@ -533,6 +652,16 @@ session_free (session *killsess)
|
|
|
8fa6cd |
current_sess = sess_list->data;
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+ if (killsess->lastact_elem)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ if (killsess->lastact_idx != LACT_NONE)
|
|
|
8fa6cd |
+ sess_list_by_lastact[killsess->lastact_idx] = g_list_delete_link(
|
|
|
8fa6cd |
+ sess_list_by_lastact[killsess->lastact_idx],
|
|
|
8fa6cd |
+ killsess->lastact_elem);
|
|
|
8fa6cd |
+ else
|
|
|
8fa6cd |
+ g_list_free_1(killsess->lastact_elem);
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
free (killsess);
|
|
|
8fa6cd |
|
|
|
8fa6cd |
if (!sess_list && !in_xchat_exit)
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/common/xchat.h xchat2/src/common/xchat.h
|
|
|
8fa6cd |
--- xchat2.orig/src/common/xchat.h 2008-07-20 17:31:44.901467675 +0200
|
|
|
8fa6cd |
+++ xchat2/src/common/xchat.h 2008-07-20 17:33:28.240467970 +0200
|
|
|
8fa6cd |
@@ -320,6 +320,15 @@ struct xchatprefs
|
|
|
8fa6cd |
#define SET_ON 1
|
|
|
8fa6cd |
#define SET_DEFAULT 2 /* use global setting */
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+/* Priorities in the "interesting sessions" priority queue
|
|
|
8fa6cd |
+ * (see xchat.c:sess_list_by_lastact) */
|
|
|
8fa6cd |
+#define LACT_NONE -1 /* no queues */
|
|
|
8fa6cd |
+#define LACT_QUERY_HI 0 /* query with hilight */
|
|
|
8fa6cd |
+#define LACT_QUERY 1 /* query with messages */
|
|
|
8fa6cd |
+#define LACT_CHAN_HI 2 /* channel with hilight */
|
|
|
8fa6cd |
+#define LACT_CHAN 3 /* channel with messages */
|
|
|
8fa6cd |
+#define LACT_CHAN_DATA 4 /* channel with other data */
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
typedef struct session
|
|
|
8fa6cd |
{
|
|
|
8fa6cd |
/* Per-Channel Alerts */
|
|
|
8fa6cd |
@@ -369,6 +378,10 @@ typedef struct session
|
|
|
8fa6cd |
|
|
|
8fa6cd |
int type; /* SESS_* */
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+ GList *lastact_elem; /* our GList element in sess_list_by_lastact */
|
|
|
8fa6cd |
+ int lastact_idx; /* the sess_list_by_lastact[] index of the list we're in.
|
|
|
8fa6cd |
+ * For valid values, see defines of LACT_*. */
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
int new_data:1; /* new data avail? (purple tab) */
|
|
|
8fa6cd |
int nick_said:1; /* your nick mentioned? (blue tab) */
|
|
|
8fa6cd |
int msg_said:1; /* new msg available? (red tab) */
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/common/xchatc.h xchat2/src/common/xchatc.h
|
|
|
8fa6cd |
--- xchat2.orig/src/common/xchatc.h 2008-07-20 17:31:44.901467675 +0200
|
|
|
8fa6cd |
+++ xchat2/src/common/xchatc.h 2008-07-20 11:43:36.673967630 +0200
|
|
|
8fa6cd |
@@ -25,10 +25,13 @@ extern GSList *ignore_list;
|
|
|
8fa6cd |
extern GSList *usermenu_list;
|
|
|
8fa6cd |
extern GSList *urlhandler_list;
|
|
|
8fa6cd |
extern GSList *tabmenu_list;
|
|
|
8fa6cd |
+extern GList *sess_list_by_lastact[];
|
|
|
8fa6cd |
|
|
|
8fa6cd |
session * find_channel (server *serv, char *chan);
|
|
|
8fa6cd |
session * find_dialog (server *serv, char *nick);
|
|
|
8fa6cd |
session * new_ircwindow (server *serv, char *name, int type, int focus);
|
|
|
8fa6cd |
+void lastact_update (session * sess);
|
|
|
8fa6cd |
+session * lastact_getfirst (int (*filter) (session *sess));
|
|
|
8fa6cd |
int is_session (session * sess);
|
|
|
8fa6cd |
void session_free (session *killsess);
|
|
|
8fa6cd |
void lag_check (void);
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/fe-gtk/fe-gtk.c xchat2/src/fe-gtk/fe-gtk.c
|
|
|
8fa6cd |
--- xchat2.orig/src/fe-gtk/fe-gtk.c 2008-07-20 17:31:44.958466232 +0200
|
|
|
8fa6cd |
+++ xchat2/src/fe-gtk/fe-gtk.c 2008-07-19 19:58:57.431961788 +0200
|
|
|
8fa6cd |
@@ -603,6 +603,7 @@ fe_print_text (struct session *sess, cha
|
|
|
8fa6cd |
sess->gui->is_tab && !sess->nick_said && stamp == 0)
|
|
|
8fa6cd |
{
|
|
|
8fa6cd |
sess->new_data = TRUE;
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
if (sess->msg_said)
|
|
|
8fa6cd |
fe_set_tab_color (sess, 2);
|
|
|
8fa6cd |
else
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/fe-gtk/fkeys.c xchat2/src/fe-gtk/fkeys.c
|
|
|
8fa6cd |
--- xchat2.orig/src/fe-gtk/fkeys.c 2008-07-20 17:31:44.960465847 +0200
|
|
|
8fa6cd |
+++ xchat2/src/fe-gtk/fkeys.c 2008-07-20 12:20:50.186930065 +0200
|
|
|
8fa6cd |
@@ -158,7 +158,7 @@ static const struct key_action key_actio
|
|
|
8fa6cd |
{key_action_handle_command, "Run Command",
|
|
|
8fa6cd |
N_("The \002Run Command\002 action runs the data in Data 1 as if it has been typed into the entry box where you pressed the key sequence. Thus it can contain text (which will be sent to the channel/person), commands or user commands. When run all \002\\n\002 characters in Data 1 are used to deliminate seperate commands so it is possible to run more than one command. If you want a \002\\\002 in the actual text run then enter \002\\\\\002")},
|
|
|
8fa6cd |
{key_action_page_switch, "Change Page",
|
|
|
8fa6cd |
- N_("The \002Change Page\002 command switches between pages in the notebook. Set Data 1 to the page you want to switch to. If Data 2 is set to anything then the switch will be relative to the current position")},
|
|
|
8fa6cd |
+ N_("The \002Change Page\002 command switches between pages in the notebook. Set Data 1 to the page you want to switch to. If Data 2 is set to anything then the switch will be relative to the current position. Set Data 1 to auto to switch to the page with the most recent and important activity (queries first, then channels with hilight, channels with dialogue, channels with other data)")},
|
|
|
8fa6cd |
{key_action_insert, "Insert in Buffer",
|
|
|
8fa6cd |
N_("The \002Insert in Buffer\002 command will insert the contents of Data 1 into the entry where the key sequence was pressed at the current cursor position")},
|
|
|
8fa6cd |
{key_action_scroll_page, "Scroll Page",
|
|
|
8fa6cd |
@@ -402,6 +402,7 @@ key_load_defaults ()
|
|
|
8fa6cd |
"A\n3\nChange Page\nD1:3\nD2!\n\n"\
|
|
|
8fa6cd |
"A\n2\nChange Page\nD1:2\nD2!\n\n"\
|
|
|
8fa6cd |
"A\n1\nChange Page\nD1:1\nD2!\n\n"\
|
|
|
8fa6cd |
+ "A\ngrave\nChange Page\nD1:auto\nD2!\n\n"\
|
|
|
8fa6cd |
"C\no\nInsert in Buffer\nD1:?\nD2!\n\n"\
|
|
|
8fa6cd |
"C\nb\nInsert in Buffer\nD1:?\nD2!\n\n"\
|
|
|
8fa6cd |
"C\nk\nInsert in Buffer\nD1:?\nD2!\n\n"\
|
|
|
8fa6cd |
@@ -1196,6 +1197,20 @@ key_action_handle_command (GtkWidget * w
|
|
|
8fa6cd |
return 0;
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+/*
|
|
|
8fa6cd |
+ * Check if the given session is inside the main window. This predicate
|
|
|
8fa6cd |
+ * is passed to lastact_pop as a way to filter out detached sessions.
|
|
|
8fa6cd |
+ * XXX: Consider moving this in a different file?
|
|
|
8fa6cd |
+ */
|
|
|
8fa6cd |
+static int
|
|
|
8fa6cd |
+session_check_is_tab(session *sess)
|
|
|
8fa6cd |
+{
|
|
|
8fa6cd |
+ if (!sess || !sess->gui)
|
|
|
8fa6cd |
+ return FALSE;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ return (sess->gui->is_tab);
|
|
|
8fa6cd |
+}
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
static int
|
|
|
8fa6cd |
key_action_page_switch (GtkWidget * wid, GdkEventKey * evt, char *d1,
|
|
|
8fa6cd |
char *d2, struct session *sess)
|
|
|
8fa6cd |
@@ -1209,6 +1224,30 @@ key_action_page_switch (GtkWidget * wid,
|
|
|
8fa6cd |
if (!len)
|
|
|
8fa6cd |
return 1;
|
|
|
8fa6cd |
|
|
|
8fa6cd |
+ if (strcasecmp(d1, "auto") == 0)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ /* Auto switch makes no sense in detached sessions */
|
|
|
8fa6cd |
+ if (!sess->gui->is_tab)
|
|
|
8fa6cd |
+ return 1;
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ /* Obtain a session with recent activity */
|
|
|
8fa6cd |
+ session *newsess = lastact_getfirst(session_check_is_tab);
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
+ if (newsess)
|
|
|
8fa6cd |
+ {
|
|
|
8fa6cd |
+ /*
|
|
|
8fa6cd |
+ * Only sessions in the current window should be considered (i.e.
|
|
|
8fa6cd |
+ * we don't want to move the focus on a different window). This
|
|
|
8fa6cd |
+ * call could, in theory, do this, but we checked before that
|
|
|
8fa6cd |
+ * newsess->gui->is_tab and sess->gui->is_tab.
|
|
|
8fa6cd |
+ */
|
|
|
8fa6cd |
+ mg_bring_tofront_sess(newsess);
|
|
|
8fa6cd |
+ return 0;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+ else
|
|
|
8fa6cd |
+ return 1;
|
|
|
8fa6cd |
+ }
|
|
|
8fa6cd |
+
|
|
|
8fa6cd |
for (i = 0; i < len; i++)
|
|
|
8fa6cd |
{
|
|
|
8fa6cd |
if (d1[i] < '0' || d1[i] > '9')
|
|
|
8fa6cd |
diff -paur xchat2.orig/src/fe-gtk/maingui.c xchat2/src/fe-gtk/maingui.c
|
|
|
8fa6cd |
--- xchat2.orig/src/fe-gtk/maingui.c 2008-07-20 17:31:44.964469466 +0200
|
|
|
8fa6cd |
+++ xchat2/src/fe-gtk/maingui.c 2008-07-19 19:58:58.255909127 +0200
|
|
|
8fa6cd |
@@ -359,6 +359,7 @@ fe_set_tab_color (struct session *sess,
|
|
|
8fa6cd |
|
|
|
8fa6cd |
break;
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
}
|
|
|
8fa6cd |
|
|
|
8fa6cd |
@@ -643,6 +644,7 @@ mg_focus (session *sess)
|
|
|
8fa6cd |
sess->nick_said = FALSE;
|
|
|
8fa6cd |
sess->msg_said = FALSE;
|
|
|
8fa6cd |
sess->new_data = FALSE;
|
|
|
8fa6cd |
+ lastact_update(sess);
|
|
|
8fa6cd |
/* when called via mg_changui_new, is_tab might be true, but
|
|
|
8fa6cd |
sess->res->tab is still NULL. */
|
|
|
8fa6cd |
if (sess->res->tab)
|