[retro-gtk] Add RetroInput
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] Add RetroInput
- Date: Sun, 29 Oct 2017 21:37:57 +0000 (UTC)
commit 8d6b039535d875bd20d96151878219d440649907
Author: Adrien Plazas <kekun plazas laposte net>
Date: Sun Oct 29 20:07:47 2017 +0100
Add RetroInput
retro-gtk/Makefile.am | 3 +
retro-gtk/retro-controller.c | 12 +-
retro-gtk/retro-controller.h | 14 +-
retro-gtk/retro-core-view-controller.c | 12 +-
retro-gtk/retro-core-view-controller.h | 1 -
retro-gtk/retro-core-view.c | 21 ++-
retro-gtk/retro-core-view.h | 8 +-
retro-gtk/retro-core.c | 20 +--
retro-gtk/retro-core.h | 10 +-
retro-gtk/retro-environment.c | 6 +-
retro-gtk/retro-gtk.h | 1 +
retro-gtk/retro-input-private.h | 69 +++++++++
retro-gtk/retro-input.c | 259 ++++++++++++++++++++++++++++++++
retro-gtk/retro-input.h | 43 ++++++
14 files changed, 419 insertions(+), 60 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index b07636e..34b216d 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -36,6 +36,7 @@ retro_gtk_public_h_sources = \
retro-core.h \
retro-core-view.h \
retro-gtk.h \
+ retro-input.h \
retro-log.h \
retro-main-loop.h \
retro-memory-type.h \
@@ -55,6 +56,7 @@ retro_gtk_private_h_sources = \
retro-disk-control-callback.h \
retro-game-info.h \
retro-input-descriptor.h \
+ retro-input-private.h \
retro-keyboard-key.h \
retro-module.h \
retro-option.h \
@@ -78,6 +80,7 @@ libretro_gtk_la_SOURCES = \
retro-core-view.c \
retro-core-view-controller.c \
retro-game-info.c \
+ retro-input.c \
retro-input-descriptor.c \
retro-keyboard-key.c \
retro-log.c \
diff --git a/retro-gtk/retro-controller.c b/retro-gtk/retro-controller.c
index 177bdc1..4af5b8d 100644
--- a/retro-gtk/retro-controller.c
+++ b/retro-gtk/retro-controller.c
@@ -32,19 +32,15 @@ retro_controller_poll (RetroController *self)
/**
* retro_controller_get_input_state:
* @self: a #RetroController
- * @controller_type: a #RetroControllerType to query @self
- * @index: an input index to interpret depending on @controller_type
- * @id: an input id to interpret depending on @controller_type
+ * @input: a #RetroInput to query @self
*
* Gets the state of an input of @self.
*
* Returns: the input's state
*/
gint16
-retro_controller_get_input_state (RetroController *self,
- RetroControllerType controller_type,
- guint index,
- guint id)
+retro_controller_get_input_state (RetroController *self,
+ RetroInput *input)
{
RetroControllerInterface *iface;
@@ -54,7 +50,7 @@ retro_controller_get_input_state (RetroController *self,
g_return_val_if_fail (iface->get_input_state != NULL, 0);
- return iface->get_input_state (self, controller_type, index, id);
+ return iface->get_input_state (self, input);
}
/**
diff --git a/retro-gtk/retro-controller.h b/retro-gtk/retro-controller.h
index 32aa2bf..af05154 100644
--- a/retro-gtk/retro-controller.h
+++ b/retro-gtk/retro-controller.h
@@ -8,7 +8,7 @@
#endif
#include <glib-object.h>
-#include "retro-controller-type.h"
+#include "retro-input.h"
#include "retro-rumble-effect.h"
G_BEGIN_DECLS
@@ -22,19 +22,15 @@ struct _RetroControllerInterface
GTypeInterface parent_iface;
void (*poll) (RetroController *self);
- gint16 (*get_input_state) (RetroController *self,
- RetroControllerType controller_type,
- guint index,
- guint id);
+ gint16 (*get_input_state) (RetroController *self,
+ RetroInput *input);
RetroControllerType (*get_controller_type) (RetroController *self);
guint64 (*get_capabilities) (RetroController *self);
};
void retro_controller_poll (RetroController *self);
-gint16 retro_controller_get_input_state (RetroController *self,
- RetroControllerType controller_type,
- guint index,
- guint id);
+gint16 retro_controller_get_input_state (RetroController *self,
+ RetroInput *input);
RetroControllerType retro_controller_get_controller_type (RetroController *self);
guint64 retro_controller_get_capabilities (RetroController *self);
gboolean retro_controller_set_rumble_state (RetroController *self,
diff --git a/retro-gtk/retro-core-view-controller.c b/retro-gtk/retro-core-view-controller.c
index 82329e7..565da17 100644
--- a/retro-gtk/retro-core-view-controller.c
+++ b/retro-gtk/retro-core-view-controller.c
@@ -25,10 +25,8 @@ retro_core_view_controller_poll (RetroController *base)
}
static gint16
-retro_core_view_controller_get_input_state (RetroController *base,
- RetroControllerType controller_type,
- guint index,
- guint id)
+retro_core_view_controller_get_input_state (RetroController *base,
+ RetroInput *input)
{
RetroCoreViewController *self = RETRO_CORE_VIEW_CONTROLLER (base);
gpointer view;
@@ -36,7 +34,7 @@ retro_core_view_controller_get_input_state (RetroController *base,
g_return_val_if_fail (self != NULL, 0);
- if (controller_type != self->controller_type)
+ if (retro_input_get_controller_type (input) != self->controller_type)
return 0;
view = g_weak_ref_get (&self->view);
@@ -44,9 +42,7 @@ retro_core_view_controller_get_input_state (RetroController *base,
if (view == NULL)
return 0;
- result = retro_core_view_get_input_state (RETRO_CORE_VIEW (view),
- self->controller_type,
- index, id);
+ result = retro_core_view_get_input_state (RETRO_CORE_VIEW (view), input);
g_object_unref (G_OBJECT (view));
diff --git a/retro-gtk/retro-core-view-controller.h b/retro-gtk/retro-core-view-controller.h
index 6cf5e24..dae8587 100644
--- a/retro-gtk/retro-core-view-controller.h
+++ b/retro-gtk/retro-core-view-controller.h
@@ -8,7 +8,6 @@
#endif
#include <glib-object.h>
-#include "retro-controller-type.h"
#include "retro-core-view.h"
G_BEGIN_DECLS
diff --git a/retro-gtk/retro-core-view.c b/retro-gtk/retro-core-view.c
index 935a1e3..c4cf2b5 100644
--- a/retro-gtk/retro-core-view.c
+++ b/retro-gtk/retro-core-view.c
@@ -621,31 +621,31 @@ retro_core_view_as_controller (RetroCoreView *self,
/**
* retro_core_view_get_input_state:
* @self: a #RetroCoreView
- * @controller_type: a #RetroControllerType to query @self
- * @index: an input index to interpret depending on @device
- * @id: an input id to interpret depending on @device
+ * @input: a #RetroInput to query @self
*
* Gets the state of an input of @self.
*
* Returns: the input's state
*/
gint16
-retro_core_view_get_input_state (RetroCoreView *self,
- RetroControllerType controller_type,
- guint index,
- guint id)
+retro_core_view_get_input_state (RetroCoreView *self,
+ RetroInput *input)
{
+ guint id;
gint16 result;
g_return_val_if_fail (RETRO_IS_CORE_VIEW (self), 0);
- switch (controller_type) {
+ switch (retro_input_get_controller_type (input)) {
case RETRO_CONTROLLER_TYPE_JOYPAD:
- if (id >= RETRO_JOYPAD_ID_COUNT)
+ if (!retro_input_get_joypad_id (input, &id))
return 0;
return retro_core_view_get_joypad_button_state (self, id) ? G_MAXINT16 : 0;
case RETRO_CONTROLLER_TYPE_MOUSE:
+ if (!retro_input_get_mouse_id (input, &id))
+ return 0;
+
switch (id) {
case RETRO_MOUSE_ID_X:
result = (gint16) self->mouse_x_delta;
@@ -665,6 +665,9 @@ retro_core_view_get_input_state (RetroCoreView *self,
return 0;
}
case RETRO_CONTROLLER_TYPE_POINTER:
+ if (!retro_input_get_pointer_id (input, &id))
+ return 0;
+
switch (id) {
case RETRO_POINTER_ID_X:
return axis_to_retro_axis (self->pointer_x);
diff --git a/retro-gtk/retro-core-view.h b/retro-gtk/retro-core-view.h
index 785fc10..baaaeb0 100644
--- a/retro-gtk/retro-core-view.h
+++ b/retro-gtk/retro-core-view.h
@@ -10,7 +10,7 @@
#include <gtk/gtk.h>
#include "retro-core.h"
#include "retro-controller.h"
-#include "retro-controller-type.h"
+#include "retro-input.h"
#include "retro-video-filter.h"
G_BEGIN_DECLS
@@ -30,10 +30,8 @@ void retro_core_view_set_filter (RetroCoreView *self,
RetroVideoFilter filter);
RetroController *retro_core_view_as_controller (RetroCoreView *self,
RetroControllerType controller_type);
-gint16 retro_core_view_get_input_state (RetroCoreView *self,
- RetroControllerType controller_type,
- guint index,
- guint id);
+gint16 retro_core_view_get_input_state (RetroCoreView *self,
+ RetroInput *input);
guint64 retro_core_view_get_controller_capabilities (RetroCoreView *self);
gboolean retro_core_view_get_can_grab_pointer (RetroCoreView *self);
void retro_core_view_set_can_grab_pointer (RetroCoreView *self,
diff --git a/retro-gtk/retro-core.c b/retro-gtk/retro-core.c
index 3758ce2..28f5600 100644
--- a/retro-gtk/retro-core.c
+++ b/retro-gtk/retro-core.c
@@ -1734,9 +1734,7 @@ retro_core_poll_controllers (RetroCore *self)
* retro_core_get_controller_input_state:
* @self: a #RetroCore
* @port: the port number
- * @controller_type: a #RetroControllerType to query @self
- * @index: an input index to interpret depending on @controller_type
- * @id: an input id to interpret depending on @controller_type
+ * @input: a #RetroInput
*
* Gets the state of an input of the controller plugged into the given port of
* @self.
@@ -1744,11 +1742,9 @@ retro_core_poll_controllers (RetroCore *self)
* Returns: the input's state
*/
gint16
-retro_core_get_controller_input_state (RetroCore *self,
- guint port,
- RetroControllerType controller_type,
- guint index,
- guint id)
+retro_core_get_controller_input_state (RetroCore *self,
+ guint port,
+ RetroInput *input)
{
RetroController *controller;
@@ -1762,13 +1758,11 @@ retro_core_get_controller_input_state (RetroCore *self,
if (controller == NULL)
return 0;
- if ((retro_controller_get_capabilities (controller) & (1 << controller_type)) == 0)
+ if ((retro_controller_get_capabilities (controller) &
+ (1 << retro_input_get_controller_type (input))) == 0)
return 0;
- return retro_controller_get_input_state (controller,
- controller_type,
- index,
- id);
+ return retro_controller_get_input_state (controller, input);
}
// FIXME documentation
diff --git a/retro-gtk/retro-core.h b/retro-gtk/retro-core.h
index 0f9e111..1ba15d2 100644
--- a/retro-gtk/retro-core.h
+++ b/retro-gtk/retro-core.h
@@ -9,7 +9,7 @@
#include <gtk/gtk.h>
#include "retro-controller-iterator.h"
-#include "retro-controller-type.h"
+#include "retro-input.h"
#include "retro-memory-type.h"
G_BEGIN_DECLS
@@ -57,11 +57,9 @@ void retro_core_set_memory (RetroCore *self,
RetroMemoryType memory_type,
GBytes *bytes);
void retro_core_poll_controllers (RetroCore *self);
-gint16 retro_core_get_controller_input_state (RetroCore *self,
- uint port,
- RetroControllerType controller_type,
- guint index,
- guint id);
+gint16 retro_core_get_controller_input_state (RetroCore *self,
+ uint port,
+ RetroInput *input);
guint64 retro_core_get_controller_capabilities (RetroCore *self);
void retro_core_set_controller (RetroCore *self,
guint port,
diff --git a/retro-gtk/retro-environment.c b/retro-gtk/retro-environment.c
index b294b23..645fdc3 100644
--- a/retro-gtk/retro-environment.c
+++ b/retro-gtk/retro-environment.c
@@ -3,6 +3,7 @@
#include "retro-core-private.h"
#include "libretro-environment.h"
+#include "retro-input-private.h"
#include "retro-pixdata-private.h"
void retro_core_set_system_av_info (RetroCore *self,
@@ -500,13 +501,16 @@ on_input_state (guint port,
guint id)
{
RetroCore *self;
+ RetroInput input;
self = retro_core_get_cb_data ();
if (self == NULL)
g_return_val_if_reached (0);
- return retro_core_get_controller_input_state (self, port, device, index, id);
+ retro_input_init (&input, device, id, index);
+
+ return retro_core_get_controller_input_state (self, port, &input);
}
// TODO This is internal, make it private as soon as possible.
diff --git a/retro-gtk/retro-gtk.h b/retro-gtk/retro-gtk.h
index 58204e1..8ac0437 100644
--- a/retro-gtk/retro-gtk.h
+++ b/retro-gtk/retro-gtk.h
@@ -15,6 +15,7 @@
#include "retro-core.h"
#include "retro-core-descriptor.h"
#include "retro-core-view.h"
+#include "retro-input.h"
#include "retro-log.h"
#include "retro-main-loop.h"
#include "retro-memory-type.h"
diff --git a/retro-gtk/retro-input-private.h b/retro-gtk/retro-input-private.h
new file mode 100644
index 0000000..ce3497c
--- /dev/null
+++ b/retro-gtk/retro-input-private.h
@@ -0,0 +1,69 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_INPUT_PRIVATE_H
+#define RETRO_INPUT_PRIVATE_H
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include "retro-input.h"
+
+G_BEGIN_DECLS
+
+typedef struct _RetroInputAny RetroInputAny;
+typedef struct _RetroInputJoypad RetroInputJoypad;
+typedef struct _RetroInputMouse RetroInputMouse;
+typedef struct _RetroInputLightgun RetroInputLightgun;
+typedef struct _RetroInputAnalog RetroInputAnalog;
+typedef struct _RetroInputPointer RetroInputPointer;
+
+struct _RetroInputAny {
+ RetroControllerType type;
+ gint id;
+ gint index;
+};
+
+struct _RetroInputJoypad {
+ RetroControllerType type;
+ RetroJoypadId id;
+};
+
+struct _RetroInputMouse {
+ RetroControllerType type;
+ RetroMouseId id;
+};
+
+struct _RetroInputLightgun {
+ RetroControllerType type;
+ RetroLightgunId id;
+};
+
+struct _RetroInputAnalog {
+ RetroControllerType type;
+ RetroAnalogId id;
+ RetroAnalogIndex index;
+};
+
+struct _RetroInputPointer {
+ RetroControllerType type;
+ RetroPointerId id;
+};
+
+union _RetroInput {
+ RetroInputAny any;
+ RetroInputJoypad joypad;
+ RetroInputMouse mouse;
+ RetroInputLightgun lightgun;
+ RetroInputAnalog analog;
+ RetroInputPointer pointer;
+};
+
+void retro_input_init (RetroInput *self,
+ RetroControllerType controller_type,
+ guint id,
+ guint index);
+
+G_END_DECLS
+
+#endif /* RETRO_INPUT_PRIVATE_H */
diff --git a/retro-gtk/retro-input.c b/retro-gtk/retro-input.c
new file mode 100644
index 0000000..052c084
--- /dev/null
+++ b/retro-gtk/retro-input.c
@@ -0,0 +1,259 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-input-private.h"
+
+G_DEFINE_BOXED_TYPE (RetroInput, retro_input, retro_input_copy, retro_input_free)
+
+/* Private */
+
+/**
+ * retro_input_init:
+ * @self: a #RetroInput
+ * @controller_type: the controller type
+ * @id: the id
+ * @index: the index
+ *
+ * Initializes @self with the given parameters.
+ */
+void
+retro_input_init (RetroInput *self,
+ RetroControllerType controller_type,
+ guint id,
+ guint index)
+{
+ g_return_if_fail (self != NULL);
+
+ self->any.type = controller_type;
+ self->any.id = id;
+ self->any.index = index;
+}
+
+/* Public */
+
+/**
+ * retro_input_new:
+ *
+ * Creates a new #RetroInput.
+ *
+ * Returns: (transfer full): a new #RetroInput, use retro_input_free() to free
+ * it
+ */
+RetroInput *
+retro_input_new (void)
+{
+ RetroInput *self;
+
+ self = g_slice_new0 (RetroInput);
+
+ return self;
+}
+
+/**
+ * retro_input_copy:
+ * @self: a #RetroInput
+ *
+ * Copies @self into a new #RetroInput.
+ *
+ * Returns: (transfer full): a new #RetroInput, use retro_input_free() to free
+ * it
+ */
+RetroInput *
+retro_input_copy (RetroInput *self)
+{
+ RetroInput *copy;
+
+ g_return_val_if_fail (self != NULL, NULL);
+
+ copy = retro_input_new ();
+ copy->any.type = self->any.type;
+ copy->any.id = self->any.id;
+ copy->any.index = self->any.index;
+
+ return copy;
+}
+
+/**
+ * retro_input_free:
+ * @self: a #RetroInput
+ *
+ * Frees the given #RetroInput.
+ */
+void
+retro_input_free (RetroInput *self)
+{
+ g_return_if_fail (self != NULL);
+
+ g_slice_free (RetroInput, self);
+}
+
+/**
+ * retro_input_get_controller_type:
+ * @self: a #RetroInput
+ *
+ * Gets the controller type of @self.
+ *
+ * Returns: the controller type of @self
+ */
+RetroControllerType
+retro_input_get_controller_type (RetroInput *self)
+{
+ g_return_val_if_fail (self != NULL, RETRO_CONTROLLER_TYPE_NONE);
+
+ return self->any.type;
+}
+
+/**
+ * retro_input_get_joypad_id:
+ * @self: a #RetroInput
+ * @id: return location for the id
+ *
+ * Gets the joypad id of %self, if any.
+ *
+ * Returns: whether the id was retrieved
+ */
+gboolean
+retro_input_get_joypad_id (RetroInput *self,
+ RetroJoypadId *id)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_JOYPAD)
+ return FALSE;
+
+ if (self->joypad.id >= RETRO_JOYPAD_ID_COUNT)
+ return FALSE;
+
+ *id = self->joypad.id;
+
+ return TRUE;
+}
+
+/**
+ * retro_input_get_mouse_id:
+ * @self: a #RetroInput
+ * @id: return location for the id
+ *
+ * Gets the mouse id of %self, if any.
+ *
+ * Returns: whether the id was retrieved
+ */
+gboolean
+retro_input_get_mouse_id (RetroInput *self,
+ RetroMouseId *id)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_MOUSE)
+ return FALSE;
+
+ if (self->mouse.id >= RETRO_MOUSE_ID_COUNT)
+ return FALSE;
+
+ *id = self->mouse.id;
+
+ return TRUE;
+}
+
+/**
+ * retro_input_get_lightgun_id:
+ * @self: a #RetroInput
+ * @id: return location for the id
+ *
+ * Gets the lightgun id of %self, if any.
+ *
+ * Returns: whether the id was retrieved
+ */
+gboolean
+retro_input_get_lightgun_id (RetroInput *self,
+ RetroLightgunId *id)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_LIGHTGUN)
+ return FALSE;
+
+ if (self->lightgun.id >= RETRO_LIGHTGUN_ID_COUNT)
+ return FALSE;
+
+ *id = self->lightgun.id;
+
+ return TRUE;
+}
+
+/**
+ * retro_input_get_analog_id:
+ * @self: a #RetroInput
+ * @id: return location for the id
+ *
+ * Gets the analog id of %self, if any.
+ *
+ * Returns: whether the id was retrieved
+ */
+gboolean
+retro_input_get_analog_id (RetroInput *self,
+ RetroAnalogId *id)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_ANALOG)
+ return FALSE;
+
+ if (self->analog.id >= RETRO_ANALOG_ID_COUNT)
+ return FALSE;
+
+ *id = self->analog.id;
+
+ return TRUE;
+}
+
+/**
+ * retro_input_get_analog_index:
+ * @self: a #RetroInput
+ * @index: return location for the index
+ *
+ * Gets the analog index of %self, if any.
+ *
+ * Returns: whether the index was retrieved
+ */
+gboolean
+retro_input_get_analog_index (RetroInput *self,
+ RetroAnalogIndex *index)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_ANALOG)
+ return FALSE;
+
+ if (self->analog.index >= RETRO_ANALOG_INDEX_COUNT)
+ return FALSE;
+
+ *index = self->analog.index;
+
+ return TRUE;
+}
+
+/**
+ * retro_input_get_pointer_id:
+ * @self: a #RetroInput
+ * @id: return location for the id
+ *
+ * Gets the pointer id of %self, if any.
+ *
+ * Returns: whether the id was retrieved
+ */
+gboolean
+retro_input_get_pointer_id (RetroInput *self,
+ RetroPointerId *id)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (self->any.type != RETRO_CONTROLLER_TYPE_POINTER)
+ return FALSE;
+
+ if (self->pointer.id >= RETRO_POINTER_ID_COUNT)
+ return FALSE;
+
+ *id = self->pointer.id;
+
+ return TRUE;
+}
diff --git a/retro-gtk/retro-input.h b/retro-gtk/retro-input.h
new file mode 100644
index 0000000..cfcb577
--- /dev/null
+++ b/retro-gtk/retro-input.h
@@ -0,0 +1,43 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_INPUT_H
+#define RETRO_INPUT_H
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+#include "retro-controller-codes.h"
+#include "retro-controller-type.h"
+
+G_BEGIN_DECLS
+
+#define RETRO_TYPE_INPUT (retro_input_get_type())
+
+GType retro_input_get_type (void) G_GNUC_CONST;
+
+typedef union _RetroInput RetroInput;
+
+RetroInput *retro_input_new (void);
+RetroInput *retro_input_copy (RetroInput *self);
+void retro_input_free (RetroInput *self);
+RetroControllerType retro_input_get_controller_type (RetroInput *self);
+gboolean retro_input_get_joypad_id (RetroInput *self,
+ RetroJoypadId *id);
+gboolean retro_input_get_mouse_id (RetroInput *self,
+ RetroMouseId *id);
+gboolean retro_input_get_lightgun_id (RetroInput *self,
+ RetroLightgunId *id);
+gboolean retro_input_get_analog_id (RetroInput *self,
+ RetroAnalogId *id);
+gboolean retro_input_get_analog_index (RetroInput *self,
+ RetroAnalogIndex *index);
+gboolean retro_input_get_pointer_id (RetroInput *self,
+ RetroPointerId *id);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (RetroInput, retro_input_free)
+
+G_END_DECLS
+
+#endif /* RETRO_INPUT_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]