summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWuZhen <wuzhen@jidemail.com>2016-06-03 00:38:15 +0800
committerChih-Wei Huang <cwhuang@linux.org.tw>2016-06-27 20:08:35 +0800
commit560cea305ee46cc1f21cd1e0f3bcbd6ec59a3676 (patch)
treef9f2affe62b903f2a0a71a1a72a1fda1b44b2099
parentc597559db6fa98c6b590dc00dc08c0a148c33219 (diff)
downloadexternal_drm_gralloc-560cea305ee46cc1f21cd1e0f3bcbd6ec59a3676.zip
external_drm_gralloc-560cea305ee46cc1f21cd1e0f3bcbd6ec59a3676.tar.gz
external_drm_gralloc-560cea305ee46cc1f21cd1e0f3bcbd6ec59a3676.tar.bz2
Maintain a list of connector outputs
Refactor code to support multiple mirrored outputs following code. Change-Id: I60781d707ae68db2dbd2c4c4122b9183633a74be
-rw-r--r--gralloc_drm_freedreno.c4
-rw-r--r--gralloc_drm_intel.c6
-rw-r--r--gralloc_drm_kms.c181
-rw-r--r--gralloc_drm_nouveau.c4
-rw-r--r--gralloc_drm_pipe.c4
-rw-r--r--gralloc_drm_priv.h12
-rw-r--r--gralloc_drm_radeon.c4
7 files changed, 130 insertions, 85 deletions
diff --git a/gralloc_drm_freedreno.c b/gralloc_drm_freedreno.c
index 3da5a65..b4efee5 100644
--- a/gralloc_drm_freedreno.c
+++ b/gralloc_drm_freedreno.c
@@ -155,12 +155,12 @@ static void fd_init_kms_features(struct gralloc_drm_drv_t *drv,
{
struct fd_info *info = (struct fd_info *) drv;
- switch (drm->primary.fb_format) {
+ switch (drm->primary->fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
- drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}
diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c
index f068e07..1fd58b4 100644
--- a/gralloc_drm_intel.c
+++ b/gralloc_drm_intel.c
@@ -603,12 +603,12 @@ static void intel_init_kms_features(struct gralloc_drm_drv_t *drv,
struct drm_i915_getparam gp;
int pageflipping, id, has_blt;
- switch (drm->primary.fb_format) {
+ switch (drm->primary->fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
- drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}
@@ -665,7 +665,7 @@ static void intel_init_kms_features(struct gralloc_drm_drv_t *drv,
int pipe;
pipe = drm_intel_get_pipe_from_crtc_id(info->bufmgr,
- drm->primary.crtc_id);
+ drm->primary->crtc_id);
drm->swap_interval = (pipe >= 0) ? 1 : 0;
drm->vblank_secondary = (pipe > 0);
}
diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c
index a9095f2..82d1b88 100644
--- a/gralloc_drm_kms.c
+++ b/gralloc_drm_kms.c
@@ -263,7 +263,7 @@ static int gralloc_drm_bo_setplane(struct gralloc_drm_t *drm,
err = drmModeSetPlane(drm->fd,
plane->drm_plane->plane_id,
- drm->primary.crtc_id,
+ drm->primary->crtc_id,
bo ? bo->fb_id : 0,
0, // flags
plane->dst_x,
@@ -284,7 +284,7 @@ static int gralloc_drm_bo_setplane(struct gralloc_drm_t *drm,
ALOGE("drmModeSetPlane : error (%s) (plane %d crtc %d fb %d)",
strerror(-err),
plane->drm_plane->plane_id,
- drm->primary.crtc_id,
+ drm->primary->crtc_id,
bo ? bo->fb_id : 0);
}
@@ -306,7 +306,7 @@ static unsigned is_plane_supported(const struct gralloc_drm_t *drm,
const struct gralloc_drm_plane_t *plane)
{
/* Planes are only supported on primary pipe for now */
- return plane->drm_plane->possible_crtcs & (1 << drm->primary.pipe);
+ return plane->drm_plane->possible_crtcs & (1 << drm->primary->pipe);
}
/*
@@ -439,25 +439,25 @@ int gralloc_drm_set_plane_handle(struct gralloc_drm_t *drm,
static int drm_kms_blit_to_hdmi(struct gralloc_drm_t *drm, struct gralloc_drm_bo_t *bo)
{
int ret = 0;
- if (drm->hdmi.active && drm->hdmi.output_mode == DRM_OUTPUT_CLONED && drm->hdmi.bo) {
+ if (drm->hdmi->active && drm->hdmi->output_mode == DRM_OUTPUT_CLONED && drm->hdmi->bo) {
int dst_x1 = 0, dst_y1 = 0;
- if (drm->hdmi.bo->handle->width > bo->handle->width)
- dst_x1 = (drm->hdmi.bo->handle->width - bo->handle->width) / 2;
- if (drm->hdmi.bo->handle->height > bo->handle->height)
- dst_y1 = (drm->hdmi.bo->handle->height - bo->handle->height) / 2;
+ if (drm->hdmi->bo->handle->width > bo->handle->width)
+ dst_x1 = (drm->hdmi->bo->handle->width - bo->handle->width) / 2;
+ if (drm->hdmi->bo->handle->height > bo->handle->height)
+ dst_y1 = (drm->hdmi->bo->handle->height - bo->handle->height) / 2;
- drm->drv->blit(drm->drv, drm->hdmi.bo, bo,
+ drm->drv->blit(drm->drv, drm->hdmi->bo, bo,
dst_x1, dst_y1,
dst_x1 + bo->handle->width,
dst_y1 + bo->handle->height,
0, 0, bo->handle->width, bo->handle->height);
- ret = drmModePageFlip(drm->fd, drm->hdmi.crtc_id, drm->hdmi.bo->fb_id, 0, NULL);
+ ret = drmModePageFlip(drm->fd, drm->hdmi->crtc_id, drm->hdmi->bo->fb_id, 0, NULL);
if (ret && errno != EBUSY)
ALOGE("failed to perform page flip for hdmi (%s) (crtc %d fb %d))",
- strerror(errno), drm->hdmi.crtc_id, drm->hdmi.bo->fb_id);
+ strerror(errno), drm->hdmi->crtc_id, drm->hdmi->bo->fb_id);
}
return ret;
@@ -487,18 +487,18 @@ static int drm_kms_page_flip(struct gralloc_drm_t *drm,
if (!bo)
return 0;
- pthread_mutex_lock(&drm->hdmi_mutex);
+ pthread_mutex_lock(&drm->outputs_mutex);
drm_kms_blit_to_hdmi(drm, bo);
- pthread_mutex_unlock(&drm->hdmi_mutex);
+ pthread_mutex_unlock(&drm->outputs_mutex);
/* set planes to be displayed */
gralloc_drm_set_planes(drm);
- ret = drmModePageFlip(drm->fd, drm->primary.crtc_id, bo->fb_id,
+ ret = drmModePageFlip(drm->fd, drm->primary->crtc_id, bo->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, (void *) drm);
if (ret) {
ALOGE("failed to perform page flip for primary (%s) (crtc %d fb %d))",
- strerror(errno), drm->primary.crtc_id, bo->fb_id);
+ strerror(errno), drm->primary->crtc_id, bo->fb_id);
/* try to set mode for next frame */
if (errno != EBUSY)
drm->first_post = 1;
@@ -597,7 +597,7 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
bo = dst;
}
- ret = drm_kms_set_crtc(drm, &drm->primary, bo->fb_id);
+ ret = drm_kms_set_crtc(drm, drm->primary, bo->fb_id);
if (!ret) {
drm->first_post = 0;
drm->current_front = bo;
@@ -605,10 +605,10 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
drm->next_front = NULL;
}
- pthread_mutex_lock(&drm->hdmi_mutex);
- if (drm->hdmi.active && drm->hdmi.output_mode == DRM_OUTPUT_CLONED && drm->hdmi.bo)
- drm_kms_set_crtc(drm, &drm->hdmi, drm->hdmi.bo->fb_id);
- pthread_mutex_unlock(&drm->hdmi_mutex);
+ pthread_mutex_lock(&drm->outputs_mutex);
+ if (drm->hdmi->active && drm->hdmi->output_mode == DRM_OUTPUT_CLONED && drm->hdmi->bo)
+ drm_kms_set_crtc(drm, drm->hdmi, drm->hdmi->bo->fb_id);
+ pthread_mutex_unlock(&drm->outputs_mutex);
return ret;
}
@@ -644,12 +644,12 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo)
break;
case DRM_SWAP_SETCRTC:
drm_kms_wait_for_post(drm, 0);
- ret = drm_kms_set_crtc(drm, &drm->primary, bo->fb_id);
+ ret = drm_kms_set_crtc(drm, drm->primary, bo->fb_id);
- pthread_mutex_lock(&drm->hdmi_mutex);
- if (drm->hdmi.active && drm->hdmi.output_mode == DRM_OUTPUT_CLONED && drm->hdmi.bo)
- drm_kms_set_crtc(drm, &drm->hdmi, drm->hdmi.bo->fb_id);
- pthread_mutex_unlock(&drm->hdmi_mutex);
+ pthread_mutex_lock(&drm->outputs_mutex);
+ if (drm->hdmi->active && drm->hdmi->output_mode == DRM_OUTPUT_CLONED && drm->hdmi->bo)
+ drm_kms_set_crtc(drm, drm->hdmi, drm->hdmi->bo->fb_id);
+ pthread_mutex_unlock(&drm->outputs_mutex);
drm->current_front = bo;
break;
@@ -713,9 +713,9 @@ static void drm_kms_init_features(struct gralloc_drm_t *drm)
/* create the real front buffer */
front = gralloc_drm_bo_create(drm,
- drm->primary.mode.hdisplay,
- drm->primary.mode.vdisplay,
- drm->primary.fb_format,
+ drm->primary->mode.hdisplay,
+ drm->primary->mode.vdisplay,
+ drm->primary->fb_format,
GRALLOC_USAGE_HW_FB);
if (front && gralloc_drm_bo_add_fb(front)) {
gralloc_drm_bo_decref(front);
@@ -1015,8 +1015,8 @@ static int drm_kms_init_with_connector(struct gralloc_drm_t *drm,
connector->modes[0].name);
}
- if (property_get_bool("persist.remixos.disp_best_fit", 1) && output != &drm->primary) {
- mode = find_mode(connector, &bpp, &drm->primary.mode);
+ if (drm->primary && output != drm->primary && property_get_bool("persist.remixos.disp_best_fit", 1)) {
+ mode = find_mode(connector, &bpp, &drm->primary->mode);
} else {
mode = find_mode(connector, &bpp, NULL);
}
@@ -1053,6 +1053,28 @@ static int drm_kms_init_with_connector(struct gralloc_drm_t *drm,
return 0;
}
+static struct gralloc_drm_output*
+drm_kms_init_with_new_connector(struct gralloc_drm_t *drm, drmModeConnectorPtr connector)
+{
+ struct gralloc_drm_output *output = NULL;
+
+ for (int i=0;i<drm->output_capacity;i++) {
+ if (!drm->outputs[i].active) {
+ output = &drm->outputs[i];
+ break;
+ }
+ }
+
+ if (output && !drm_kms_init_with_connector(drm, output, connector)) {
+ drm->output_count++;
+ if (!drm->primary) {
+ drm->primary = output;
+ }
+ }
+
+ return output;
+}
+
/*
* Fetch a connector of particular type
@@ -1079,6 +1101,22 @@ static drmModeConnectorPtr fetch_connector(struct gralloc_drm_t *drm,
return NULL;
}
+static int init_connectors(struct gralloc_drm_t *drm)
+{
+ if (!drm->resources)
+ return -1;
+
+ drm->output_capacity = drm->resources->count_connectors;
+ drm->output_count = 0;
+
+ drm->outputs = malloc(sizeof(*drm->outputs) * drm->output_capacity);
+ memset(drm->outputs, 0, sizeof(*drm->outputs) * drm->output_capacity);
+
+ drm->hdmi = &drm->outputs[1];
+
+ return 0;
+}
+
/*
* Initializes hdmi output with a connector and allocates
@@ -1088,25 +1126,25 @@ static drmModeConnectorPtr fetch_connector(struct gralloc_drm_t *drm,
static int init_hdmi_output(struct gralloc_drm_t *drm,
drmModeConnectorPtr connector)
{
- drm_kms_init_with_connector(drm, &drm->hdmi, connector);
+ drm_kms_init_with_connector(drm, drm->hdmi, connector);
ALOGD("%s, allocate private buffer for hdmi [%dx%d]",
- __func__, drm->hdmi.mode.hdisplay, drm->hdmi.mode.vdisplay);
+ __func__, drm->hdmi->mode.hdisplay, drm->hdmi->mode.vdisplay);
- drm->hdmi.bo = gralloc_drm_bo_create(drm,
- drm->hdmi.mode.hdisplay, drm->hdmi.mode.vdisplay,
- drm->hdmi.fb_format,
+ drm->hdmi->bo = gralloc_drm_bo_create(drm,
+ drm->hdmi->mode.hdisplay, drm->hdmi->mode.vdisplay,
+ drm->hdmi->fb_format,
GRALLOC_USAGE_HW_RENDER);
- int err = gralloc_drm_bo_add_fb(drm->hdmi.bo);
+ int err = gralloc_drm_bo_add_fb(drm->hdmi->bo);
if (err) {
ALOGE("%s: could not create drm fb, (%s)",
__func__, strerror(-err));
return err;
}
- drm->hdmi.output_mode = DRM_OUTPUT_CLONED;
- drm->hdmi.active = 1;
+ drm->hdmi->output_mode = DRM_OUTPUT_CLONED;
+ drm->hdmi->active = 1;
return 0;
}
@@ -1141,7 +1179,7 @@ static void *hdmi_observer(void *data)
if (!strcmp(event.path, "devices/virtual/switch/hdmi")) {
if (event.switchstate != -1) {
- pthread_mutex_lock(&drm->hdmi_mutex);
+ pthread_mutex_lock(&drm->outputs_mutex);
if (event.switchstate) {
hdmi = fetch_connector(drm, DRM_MODE_CONNECTOR_HDMIA);
@@ -1155,42 +1193,42 @@ static void *hdmi_observer(void *data)
drmModeFreeConnector(hdmi);
}
} else {
- drm->hdmi.active = 0;
+ drm->hdmi->active = 0;
used_crtcs &= ~(1 << drm->hdmi.pipe);
ALOGD("destroy hdmi private buffer");
- gralloc_drm_bo_decref(drm->hdmi.bo);
- drm->hdmi.bo = NULL;
+ gralloc_drm_bo_decref(drm->hdmi->bo);
+ drm->hdmi->bo = NULL;
}
- pthread_mutex_unlock(&drm->hdmi_mutex);
+ pthread_mutex_unlock(&drm->outputs_mutex);
}
} else if (!strcmp(event.subsystem, "drm") &&
!strcmp(event.device_name, "dri/card0") && event.hotplug) {
- pthread_mutex_lock(&drm->hdmi_mutex);
+ pthread_mutex_lock(&drm->outputs_mutex);
hdmi = fetch_connector(drm, DRM_MODE_CONNECTOR_HDMIA);
- if (hdmi && !drm->hdmi.active) {
+ if (hdmi && !drm->hdmi->active) {
ALOGD("init hdmi on hotplug event");
if (!init_hdmi_output(drm, hdmi)) {
- drm_kms_set_crtc(drm, &drm->hdmi, drm->hdmi.bo->fb_id);
+ drm_kms_set_crtc(drm, drm->hdmi, drm->hdmi->bo->fb_id);
}
/* will trigger modeset */
drm->first_post = 1;
- } else if (!hdmi && drm->hdmi.active) {
- drm->hdmi.active = 0;
+ } else if (!hdmi && drm->hdmi->active) {
+ drm->hdmi->active = 0;
used_crtcs &= ~(1 << drm->hdmi.pipe);
ALOGD("destroy hdmi private buffer");
- gralloc_drm_bo_decref(drm->hdmi.bo);
- drm->hdmi.bo = NULL;
+ gralloc_drm_bo_decref(drm->hdmi->bo);
+ drm->hdmi->bo = NULL;
}
if (hdmi)
drmModeFreeConnector(hdmi);
- pthread_mutex_unlock(&drm->hdmi_mutex);
+ pthread_mutex_unlock(&drm->outputs_mutex);
}
}
@@ -1241,16 +1279,18 @@ int gralloc_drm_init_kms(struct gralloc_drm_t *drm)
}
}
+ init_connectors(drm);
+
/* find the crtc/connector/mode to use */
lvds = fetch_connector(drm, DRM_MODE_CONNECTOR_LVDS);
if (lvds) {
- drm_kms_init_with_connector(drm, &drm->primary, lvds);
+ drm_kms_init_with_new_connector(drm, lvds);
drmModeFreeConnector(lvds);
- drm->primary.active = 1;
+ drm->primary->active = 1;
}
/* if still no connector, find first connected connector and try it */
- if (!drm->primary.active) {
+ if (!drm->primary) {
for (i = 0; i < drm->resources->count_connectors; i++) {
drmModeConnectorPtr connector;
@@ -1259,9 +1299,10 @@ int gralloc_drm_init_kms(struct gralloc_drm_t *drm)
drm->resources->connectors[i]);
if (connector) {
if (connector->connection == DRM_MODE_CONNECTED) {
- if (!drm_kms_init_with_connector(drm,
- &drm->primary, connector))
+ if (drm_kms_init_with_new_connector(drm, connector)){
+ drm->primary->active = 1;
break;
+ }
}
drmModeFreeConnector(connector);
@@ -1286,7 +1327,7 @@ int gralloc_drm_init_kms(struct gralloc_drm_t *drm)
hdmi = fetch_connector(drm, DRM_MODE_CONNECTOR_HDMIA);
if (hdmi) {
- if (hdmi->connector_id == drm->primary.connector_id) {
+ if (hdmi->connector_id == drm->primary->connector_id) {
/* special case: our primary connector is hdmi */
ALOGD("hdmi is the primary connector");
goto skip_hdmi_modes;
@@ -1299,8 +1340,8 @@ int gralloc_drm_init_kms(struct gralloc_drm_t *drm)
}
/* launch hdmi observer thread */
- pthread_mutex_init(&drm->hdmi_mutex, NULL);
- pthread_create(&drm->hdmi_hotplug_thread, NULL, hdmi_observer, drm);
+ pthread_mutex_init(&drm->outputs_mutex, NULL);
+ pthread_create(&drm->hotplug_thread, NULL, hdmi_observer, drm);
skip_hdmi_modes:
@@ -1351,8 +1392,10 @@ void gralloc_drm_fini_kms(struct gralloc_drm_t *drm)
}
/* destroy private buffer of hdmi output */
- if (drm->hdmi.bo)
- gralloc_drm_bo_decref(drm->hdmi.bo);
+ if (drm->hdmi->bo)
+ gralloc_drm_bo_decref(drm->hdmi->bo);
+
+ free(drm->outputs);
drm_singleton = NULL;
}
@@ -1369,14 +1412,14 @@ void gralloc_drm_get_kms_info(struct gralloc_drm_t *drm,
struct framebuffer_device_t *fb)
{
*((uint32_t *) &fb->flags) = 0x0;
- *((uint32_t *) &fb->width) = drm->primary.mode.hdisplay;
- *((uint32_t *) &fb->height) = drm->primary.mode.vdisplay;
- *((int *) &fb->stride) = drm->primary.mode.hdisplay;
- *((float *) &fb->fps) = drm->primary.mode.vrefresh;
-
- *((int *) &fb->format) = drm->primary.fb_format;
- *((float *) &fb->xdpi) = drm->primary.xdpi;
- *((float *) &fb->ydpi) = drm->primary.ydpi;
+ *((uint32_t *) &fb->width) = drm->primary->mode.hdisplay;
+ *((uint32_t *) &fb->height) = drm->primary->mode.vdisplay;
+ *((int *) &fb->stride) = drm->primary->mode.hdisplay;
+ *((float *) &fb->fps) = drm->primary->mode.vrefresh;
+
+ *((int *) &fb->format) = drm->primary->fb_format;
+ *((float *) &fb->xdpi) = drm->primary->xdpi;
+ *((float *) &fb->ydpi) = drm->primary->ydpi;
*((int *) &fb->minSwapInterval) = drm->swap_interval;
*((int *) &fb->maxSwapInterval) = drm->swap_interval;
}
diff --git a/gralloc_drm_nouveau.c b/gralloc_drm_nouveau.c
index 30e8fcb..810cc7b 100644
--- a/gralloc_drm_nouveau.c
+++ b/gralloc_drm_nouveau.c
@@ -302,12 +302,12 @@ static void nouveau_init_kms_features(struct gralloc_drm_drv_t *drv,
{
struct nouveau_info *info = (struct nouveau_info *) drv;
- switch (drm->primary.fb_format) {
+ switch (drm->primary->fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
- drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index 00909bf..05395ff 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -344,12 +344,12 @@ static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc
{
struct pipe_manager *pm = (struct pipe_manager *) drv;
- switch (drm->primary.fb_format) {
+ switch (drm->primary->fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
- drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}
diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h
index 9203fba..e77b31c 100644
--- a/gralloc_drm_priv.h
+++ b/gralloc_drm_priv.h
@@ -98,12 +98,14 @@ struct gralloc_drm_t {
/* initialized by gralloc_drm_init_kms */
drmModeResPtr resources;
- struct gralloc_drm_output primary;
- struct gralloc_drm_output hdmi;
- /* hdmi hotplug */
- pthread_mutex_t hdmi_mutex;
- pthread_t hdmi_hotplug_thread;
+ struct gralloc_drm_output *outputs;
+ int output_count, output_capacity;
+
+ struct gralloc_drm_output *primary, *hdmi;
+
+ pthread_mutex_t outputs_mutex;
+ pthread_t hotplug_thread;
#ifdef DRM_MODE_FEATURE_DIRTYFB
drmModeClip clip;
diff --git a/gralloc_drm_radeon.c b/gralloc_drm_radeon.c
index 8320989..8fd84e9 100644
--- a/gralloc_drm_radeon.c
+++ b/gralloc_drm_radeon.c
@@ -321,12 +321,12 @@ static void drm_gem_radeon_unmap(struct gralloc_drm_drv_t *drv,
static void drm_gem_radeon_init_kms_features(struct gralloc_drm_drv_t *drv,
struct gralloc_drm_t *drm)
{
- switch (drm->primary.fb_format) {
+ switch (drm->primary->fb_format) {
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
break;
default:
- drm->primary.fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
+ drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
break;
}