修改前

修改后

6.0 Recovery 模式横屏修改方法

修改相关文件

bootable\recovery\minui\Android.mk

bootable\recovery\minui\mt_graphic_rotate.cpp

bootable\recovery\minui\mt_graphic_rotate.h

bootable\recovery\minui\graphics_fbdev.cpp

bootable\recovery\minui\minui.h

1、在 Android.mk 中增加 mt_graphic_rotate.cpp 编译项

LOCAL_SRC_FILES := \
events.cpp \
graphics.cpp \
graphics_adf.cpp \
graphics_drm.cpp \
graphics_fbdev.cpp \
resources.cpp \ #cczheng add
LOCAL_SRC_FILES += mt_graphic_rotate.cpp

2、对比修改 mt_graphic_rotate.cpp,没有则直接复制以下类

/*
* Copyright (C) 2014 MediaTek Inc.
* Modification based on code covered by the mentioned copyright
* and/or permission notice(s).
*/ #include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h> #include <fcntl.h>
#include <stdio.h> #include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h> #include <linux/fb.h>
#include <linux/kd.h> #include "minui.h"
#include "graphics.h" GRSurface __gr_canvas; GRSurface* gr_canvas = NULL;
int rotate_index=-1; static void print_surface_info(GRSurface *s, const char *name)
{
printf("[graphics] %s > Height:%d, Width:%d, PixelBytes:%d, RowBytes:%d, Size:%d, Data: 0x%08" PRIxPTR "\n",
name, s->height, s->width, s->pixel_bytes, s->row_bytes, s->height* s->row_bytes, (uintptr_t) s->data);
} // Read configuration from MTK_LCM_PHYSICAL_ROTATION
#ifndef MTK_LCM_PHYSICAL_ROTATION
#define MTK_LCM_PHYSICAL_ROTATION "undefined"
#endif
static int rotate_config(GRSurface *gr_draw)
{
if (rotate_index<0)
{
if (gr_draw->pixel_bytes != 4) rotate_index=0; // support 4 bytes pixel only
else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) rotate_index=1;
else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3)) rotate_index=2;
else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) rotate_index=3;
else rotate_index=0;
printf("[graphics] rotate_config %d %s\n", rotate_index, MTK_LCM_PHYSICAL_ROTATION);
}
return rotate_index;
} #define swap(x, y, type) {type z; z=x; x=y; y=z;} // Allocate and setup the canvas object
void rotate_canvas_init(GRSurface *gr_draw)
{
gr_canvas = &__gr_canvas;
memcpy(gr_canvas, gr_draw, sizeof(GRSurface)); // Swap canvas' height and width, if the rotate angle is 90" or 270"
if (rotate_config(gr_draw)%2) {
swap(gr_canvas->width, gr_canvas->height, int);
gr_canvas->row_bytes = gr_canvas->width * gr_canvas->pixel_bytes;
} gr_canvas->data = (unsigned char*) malloc(gr_canvas->height * gr_canvas->row_bytes);
if (gr_canvas->data == NULL) {
printf("[graphics] rotate_canvas_init() malloc gr_canvas->data failed\n");
gr_canvas = NULL;
return;
} memset(gr_canvas->data, 0, gr_canvas->height * gr_canvas->row_bytes); print_surface_info(gr_draw, "gr_draw");
print_surface_info(gr_canvas, "gr_canvas");
} // Cleanup the canvas
void rotate_canvas_exit(void)
{
if (gr_canvas) {
if (gr_canvas->data)
free(gr_canvas->data);
free(gr_canvas);
}
gr_canvas=NULL;
} // Return the canvas object
GRSurface *rotate_canvas_get(GRSurface *gr_draw)
{
// Initialize the canvas, if it was not exist.
if (gr_canvas==NULL)
rotate_canvas_init(gr_draw);
return gr_canvas;
} // Surface Rotate Routines
static void rotate_surface_0(GRSurface *dst, GRSurface *src)
{
memcpy(dst->data, src->data, src->height*src->row_bytes);
} static void rotate_surface_270(GRSurface *dst, GRSurface *src)
{
int v, w, h;
unsigned int *src_pixel;
unsigned int *dst_pixel; for (h=0, v=src->width-1; h<dst->height; h++, v--) {
for (w=0; w<dst->width; w++) {
dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
src_pixel = (unsigned int *)(src->data + src->row_bytes*w);
*(dst_pixel+w)=*(src_pixel+v);
}
}
} static void rotate_surface_180(GRSurface *dst, GRSurface *src)
{
int v, w, k, h;
unsigned int *src_pixel;
unsigned int *dst_pixel; for (h=0, k=src->height-1; h<dst->height && k>=0 ; h++, k--) {
dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
for (w=0, v=src->width-1; w<dst->width && v>=0; w++, v--) {
*(dst_pixel+w)=*(src_pixel+v);
}
}
} static void rotate_surface_90(GRSurface *dst, GRSurface *src)
{
int w, k, h;
unsigned int *src_pixel;
unsigned int *dst_pixel; for (h=0; h<dst->height; h++) {
for (w=0, k=src->height-1; w<dst->width; w++, k--) {
dst_pixel = (unsigned int *)(dst->data + dst->row_bytes*h);
src_pixel = (unsigned int *)(src->data + src->row_bytes*k);
*(dst_pixel+w)=*(src_pixel+h);
}
}
} typedef void (*rotate_surface_t) (GRSurface *, GRSurface *); rotate_surface_t rotate_func[4]=
{
rotate_surface_0,
rotate_surface_90,
rotate_surface_180,
rotate_surface_270
}; // rotate and copy src* surface to dst surface
void rotate_surface(GRSurface *dst, GRSurface *src)
{
rotate_surface_t rotate;
rotate=rotate_func[rotate_config(dst)];
rotate(dst, src);
}

3、对比修改 mt_graphic_rotate.h,没有则直接复制以下类

/*
* Copyright (C) 2014 MediaTek Inc.
* Modification based on code covered by the mentioned copyright
* and/or permission notice(s).
*/ #ifndef MT_GRAPHICS_ROTATE_H_
#define MT_GRAPHICS_ROTATE_H_ #include "minui.h" void rotate_canvas_exit(void);
void rotate_canvas_init(GRSurface *gr_draw);
void rotate_surface(GRSurface *dst, GRSurface *src);
GRSurface *rotate_canvas_get(GRSurface *gr_draw); #endif

4、对比修改 graphics_fbdev.cpp,没有则直接复制以下类

/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <fcntl.h>
#include <stdio.h> #include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h> #include <linux/fb.h>
#include <linux/kd.h> #include "minui.h"
#include "graphics.h"
#include "mt_graphic_rotate.h" static GRSurface* fbdev_init(minui_backend*);
static GRSurface* fbdev_flip(minui_backend*);
static void fbdev_blank(minui_backend*, bool);
static void fbdev_exit(minui_backend*); static GRSurface gr_framebuffer[2];
static bool double_buffered;
static GRSurface* gr_draw = NULL;
static int displayed_buffer; static fb_var_screeninfo vi;
static int fb_fd = -1; static minui_backend my_backend = {
.init = fbdev_init,
.flip = fbdev_flip,
.blank = fbdev_blank,
.exit = fbdev_exit,
}; minui_backend* open_fbdev() {
return &my_backend;
} static void fbdev_blank(minui_backend* backend __unused, bool blank)
{
int ret; ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
if (ret < 0)
perror("ioctl(): blank");
} static void set_displayed_framebuffer(unsigned n)
{
if (n > 1 || !double_buffered) return; vi.yres_virtual = gr_framebuffer[0].height * 2;
vi.yoffset = n * gr_framebuffer[0].height;
vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;
if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
displayed_buffer = n;
} static GRSurface* fbdev_init(minui_backend* backend) {
int fd = open("/dev/graphics/fb0", O_RDWR);
if (fd == -1) {
perror("cannot open fb0");
return NULL;
} fb_fix_screeninfo fi;
if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
perror("failed to get fb0 info");
close(fd);
return NULL;
} if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
perror("failed to get fb0 info");
close(fd);
return NULL;
} // We print this out for informational purposes only, but
// throughout we assume that the framebuffer device uses an RGBX
// pixel format. This is the case for every development device I
// have access to. For some of those devices (eg, hammerhead aka
// Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a
// different format (XBGR) but actually produces the correct
// results on the display when you write RGBX.
//
// If you have a device that actually *needs* another pixel format
// (ie, BGRX, or 565), patches welcome... printf("fb0 reports (possibly inaccurate):\n"
" vi.bits_per_pixel = %d\n"
" vi.red.offset = %3d .length = %3d\n"
" vi.green.offset = %3d .length = %3d\n"
" vi.blue.offset = %3d .length = %3d\n",
vi.bits_per_pixel,
vi.red.offset, vi.red.length,
vi.green.offset, vi.green.length,
vi.blue.offset, vi.blue.length); void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (bits == MAP_FAILED) {
perror("failed to mmap framebuffer");
close(fd);
return NULL;
} memset(bits, 0, fi.smem_len); gr_framebuffer[0].width = vi.xres;
gr_framebuffer[0].height = vi.yres;
gr_framebuffer[0].row_bytes = fi.line_length;
gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;
gr_framebuffer[0].data = reinterpret_cast<uint8_t*>(bits);
memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes); /* check if we can use double buffering */
printf("[graphics] vi.yres * fi.line_length = %d * %d * 2 = %d, fi.smem_len=%d\n",
vi.yres, fi.line_length, vi.yres * fi.line_length * 2, fi.smem_len); if (vi.yres * fi.line_length * 2 <= fi.smem_len) {
double_buffered = true;
printf("[graphics] double buffered\n"); memcpy(gr_framebuffer+1, gr_framebuffer, sizeof(GRSurface));
gr_framebuffer[1].data = gr_framebuffer[0].data +
gr_framebuffer[0].height * gr_framebuffer[0].row_bytes; gr_draw = gr_framebuffer+1; } else {
double_buffered = false;
printf("[graphics] without double buffer\n");
// Without double-buffering, we allocate RAM for a buffer to
// draw in, and then "flipping" the buffer consists of a
// memcpy from the buffer we allocated to the framebuffer. gr_draw = (GRSurface*) malloc(sizeof(GRSurface));
memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));
gr_draw->data = (unsigned char*) malloc(gr_draw->height * gr_draw->row_bytes);
if (!gr_draw->data) {
perror("failed to allocate in-memory surface");
return NULL;
}
} memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);
fb_fd = fd;
set_displayed_framebuffer(0); printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height); #if 0 // to avoid display blink due to display driver not disable backlight after kernel standardization, so that temp state between display suspend/resume is shown
fbdev_blank(backend, true);
fbdev_blank(backend, false);
#endif return rotate_canvas_get(gr_draw);
} static GRSurface* fbdev_flip(minui_backend* backend __unused) {
rotate_surface(gr_draw, rotate_canvas_get(gr_draw));
if (double_buffered) {
#if defined(RECOVERY_BGRA)
// In case of BGRA, do some byte swapping
unsigned int idx;
unsigned char tmp;
unsigned char* ucfb_vaddr = (unsigned char*)gr_draw->data;
for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes);
idx += 4) {
tmp = ucfb_vaddr[idx];
ucfb_vaddr[idx ] = ucfb_vaddr[idx + 2];
ucfb_vaddr[idx + 2] = tmp;
}
#endif
// Change gr_draw to point to the buffer currently displayed,
// then flip the driver so we're displaying the other buffer
// instead.
gr_draw = gr_framebuffer + displayed_buffer;
set_displayed_framebuffer(1-displayed_buffer);
} else {
// Copy from the in-memory surface to the framebuffer.
memcpy(gr_framebuffer[0].data, gr_draw->data,
gr_draw->height * gr_draw->row_bytes);
}
return rotate_canvas_get(gr_draw);
} static void fbdev_exit(minui_backend* backend __unused) {
close(fb_fd);
fb_fd = -1;
rotate_canvas_exit();
if (!double_buffered && gr_draw) {
free(gr_draw->data);
free(gr_draw);
}
gr_draw = NULL;
}

5、对比修改 minui.h,没有则直接复制以下类

/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #ifndef _MINUI_H_
#define _MINUI_H_ #include <sys/types.h> #include <functional> //
// Graphics.
// struct GRSurface {
int width;
int height;
int row_bytes;
int pixel_bytes;
unsigned char* data;
}; int gr_init();
void gr_exit(); int gr_fb_width();
int gr_fb_height(); void gr_flip();
void gr_fb_blank(bool blank); void gr_clear(); // clear entire surface to current color
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void gr_fill(int x1, int y1, int x2, int y2);
void gr_text(int x, int y, const char *s, bool bold);
void gr_texticon(int x, int y, GRSurface* icon);
int gr_measure(const char *s);
void gr_font_size(int *x, int *y); void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy);
unsigned int gr_get_width(GRSurface* surface);
unsigned int gr_get_height(GRSurface* surface); //
// Input events.
// struct input_event; // TODO: move these over to std::function.
typedef int (*ev_callback)(int fd, uint32_t epevents, void* data);
typedef int (*ev_set_key_callback)(int code, int value, void* data); int ev_init(ev_callback input_cb, void* data);
void ev_exit();
int ev_add_fd(int fd, ev_callback cb, void* data);
void ev_iterate_available_keys(std::function<void(int)> f);
int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data); // 'timeout' has the same semantics as poll(2).
// 0 : don't block
// < 0 : block forever
// > 0 : block for 'timeout' milliseconds
int ev_wait(int timeout); int ev_get_input(int fd, uint32_t epevents, input_event* ev);
void ev_dispatch();
int ev_get_epollfd(); //
// Resources
// // res_create_*_surface() functions return 0 if no error, else
// negative.
//
// A "display" surface is one that is intended to be drawn to the
// screen with gr_blit(). An "alpha" surface is a grayscale image
// interpreted as an alpha mask used to render text in the current
// color (with gr_text() or gr_texticon()).
//
// All these functions load PNG images from "/res/images/${name}.png". // Load a single display surface from a PNG image.
int res_create_display_surface(const char* name, GRSurface** pSurface); // Load an array of display surfaces from a single PNG image. The PNG
// should have a 'Frames' text chunk whose value is the number of
// frames this image represents. The pixel data itself is interlaced
// by row.
int res_create_multi_display_surface(const char* name,
int* frames, GRSurface*** pSurface); // Load a single alpha surface from a grayscale PNG image.
int res_create_alpha_surface(const char* name, GRSurface** pSurface); // Load part of a grayscale PNG image that is the first match for the
// given locale. The image is expected to be a composite of multiple
// translations of the same text, with special added rows that encode
// the subimages' size and intended locale in the pixel data. See
// development/tools/recovery_l10n for an app that will generate these
// specialized images from Android resources.
int res_create_localized_alpha_surface(const char* name, const char* locale,
GRSurface** pSurface); // Free a surface allocated by any of the res_create_*_surface()
// functions.
void res_free_surface(GRSurface* surface); #endif

8.1 Recovery 模式横屏修改方法

8.1 的修改步骤和 6.0 大体差不多,前三步都一样,请参考上面的,由于 8.1 中不需要 minui.h 文件,所以 mt_graphic_rotate.hmt_graphic_rotate.cpp 中 需要注释

//#include "minui.h"

4、对比修改 graphics_fbdev.cpp

/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #include "graphics_fbdev.h" #include <fcntl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h> #include "minui/minui.h"
//cczheng add for rotateCanvas
#include "mt_graphic_rotate.h" MinuiBackendFbdev::MinuiBackendFbdev() : gr_draw(nullptr), fb_fd(-1) {} void MinuiBackendFbdev::Blank(bool blank) {
int ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
if (ret < 0) perror("ioctl(): blank");
} void MinuiBackendFbdev::SetDisplayedFramebuffer(unsigned n) {
if (n > 1 || !double_buffered) return; vi.yres_virtual = gr_framebuffer[0].height * 2;
vi.yoffset = n * gr_framebuffer[0].height;
vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;
if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
displayed_buffer = n;
} GRSurface* MinuiBackendFbdev::Init() {
int fd = open("/dev/graphics/fb0", O_RDWR);
if (fd == -1) {
perror("cannot open fb0");
return nullptr;
} fb_fix_screeninfo fi;
if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
perror("failed to get fb0 info");
close(fd);
return nullptr;
} if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
perror("failed to get fb0 info");
close(fd);
return nullptr;
} // We print this out for informational purposes only, but
// throughout we assume that the framebuffer device uses an RGBX
// pixel format. This is the case for every development device I
// have access to. For some of those devices (eg, hammerhead aka
// Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a
// different format (XBGR) but actually produces the correct
// results on the display when you write RGBX.
//
// If you have a device that actually *needs* another pixel format
// (ie, BGRX, or 565), patches welcome... printf(
"fb0 reports (possibly inaccurate):\n"
" vi.bits_per_pixel = %d\n"
" vi.red.offset = %3d .length = %3d\n"
" vi.green.offset = %3d .length = %3d\n"
" vi.blue.offset = %3d .length = %3d\n",
vi.bits_per_pixel, vi.red.offset, vi.red.length, vi.green.offset, vi.green.length,
vi.blue.offset, vi.blue.length); void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (bits == MAP_FAILED) {
perror("failed to mmap framebuffer");
close(fd);
return nullptr;
} memset(bits, 0, fi.smem_len); gr_framebuffer[0].width = vi.xres;
gr_framebuffer[0].height = vi.yres;
gr_framebuffer[0].row_bytes = fi.line_length;
gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;
gr_framebuffer[0].data = static_cast<uint8_t*>(bits);
memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes); /* check if we can use double buffering */
if (vi.yres * fi.line_length * 2 <= fi.smem_len) {
double_buffered = true; memcpy(gr_framebuffer + 1, gr_framebuffer, sizeof(GRSurface));
gr_framebuffer[1].data =
gr_framebuffer[0].data + gr_framebuffer[0].height * gr_framebuffer[0].row_bytes; gr_draw = gr_framebuffer + 1; } else {
double_buffered = false; // Without double-buffering, we allocate RAM for a buffer to
// draw in, and then "flipping" the buffer consists of a
// memcpy from the buffer we allocated to the framebuffer. gr_draw = static_cast<GRSurface*>(malloc(sizeof(GRSurface)));
memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));
gr_draw->data = static_cast<unsigned char*>(malloc(gr_draw->height * gr_draw->row_bytes));
if (!gr_draw->data) {
perror("failed to allocate in-memory surface");
return nullptr;
}
} memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);
fb_fd = fd;
SetDisplayedFramebuffer(0); printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height);
#if 0
Blank(true);
Blank(false);
#endif //return gr_draw;
//cczheng add for rotateCanvas
return rotate_canvas_get(gr_draw);
} GRSurface* MinuiBackendFbdev::Flip() {
//cczheng add for rotateCanvas
rotate_surface(gr_draw, rotate_canvas_get(gr_draw));
if (double_buffered) {
// Change gr_draw to point to the buffer currently displayed,
// then flip the driver so we're displaying the other buffer
// instead.
gr_draw = gr_framebuffer + displayed_buffer;
SetDisplayedFramebuffer(1 - displayed_buffer);
} else {
// Copy from the in-memory surface to the framebuffer.
memcpy(gr_framebuffer[0].data, gr_draw->data, gr_draw->height * gr_draw->row_bytes);
}
//return gr_draw;
//cczheng add for rotateCanvas
return rotate_canvas_get(gr_draw);
} MinuiBackendFbdev::~MinuiBackendFbdev() {
close(fb_fd);
fb_fd = -1;
//cczheng add for rotateCanvas
rotate_canvas_exit();
if (!double_buffered && gr_draw) {
free(gr_draw->data);
free(gr_draw);
}
gr_draw = nullptr;
}

修改旋转角度,在 mt_graphic_rotate.cpp 中的 rotate_config(GRSurface gr_draw)

旋转90度就将 return rotate_index 直接改为 return 1,

依次类推转 180度, 改为 return 2, 270 度改为 return 3.

注意旋转方向为顺时针旋转

我修改的情况对应 return 3.

MTK Recovery 模式横屏修改(适用于6.0 + 8.1)的更多相关文章

  1. ubuntu 如何在recovery模式修改root密码

    今天遇到一个问题, 前提1: ubuntu系统的root密码我一直没有设定  前提2: ubuntu初始创建的sudo用户不知道怎么移除sudo权限用户了. 下面就精彩了, 首先没有root密码,你不 ...

  2. [RK3288][Android6.0] 调试笔记 --- 系统第一次开机进入Recovery模式原因【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/53464461 latform: ROCKCHIPOS: Android 6.0Kernel: ...

  3. FastBoot BootLoader Recovery 模式解释

    理论上,所有的Android设备都存在着Fastboot/Bootloader模式,不过,由于Android操作系统的开源特性,各厂商的对 自家的相关Android设备都有着各自不同的Fastboot ...

  4. Linux学习之CentOS(二十二)--单用户模式下修改Root用户的密码

    在上一篇随笔里面详细讲解了Linux系统的启动过程 (Linux学习之CentOS(二十一)--Linux系统启动详解),我们知道Linux系统的启动级别一共有6种级别,通过 /etc/inittab ...

  5. android recovery模式及ROM制作

    转自android recovery模式及ROM制作 1.总述 为了方便客户日后的固件升级,本周研究了一下android的recovery模式.网上有不少这类的资料,但都比较繁杂,没有一个系统的介绍与 ...

  6. Centos 进入recovery模式,单用户模式

    1.重启服务器,在选择内核界面使用上下箭头移动 2.选择内核并按“e” 3.找到下面这行 4.修改 这里要删除掉rhgb quiet,如下图 5.使用“ctrl + x” 来重启服务器就可以了,重启后 ...

  7. Linux单用户模式(修改密码、运行级别)方法详解

    很多新手当面对"忘记 root 账户密码导致无法登陆系统"这个问题时,直接选择重新系统.其实大可不必,我只需要进入 emergency mode(单用户模式)更新 root 账户的 ...

  8. Ultraedit和写字板修改Tomcat 6.0的server.xml不生效

    转:http://blog.csdn.net/greencacti/article/details/6615321 本人在修改Tomcat 6.0的server.xml的时候,发现写字板修改完保存的时 ...

  9. Fastboot模式和Recovery模式

    http://blog.csdn.net/luoshengyang/article/details/29688041 在回答第一个问题之前,我们先来看看Android设备从硬件到系统的结构,如图1所示 ...

随机推荐

  1. Java 从入门到进阶之路(十二)

    在之前的文章我们介绍了一下 Java 类的重写及与重载的区别,本章我们来看一下 Java 类的 private,static,final. 我们在之前引入 Java 类概念的时候是通过商场收银台来引入 ...

  2. 洛谷 题解 P1842 【奶牛玩杂技】

    本蒟蒻又双叒叕被爆踩辣! Solution: 我们先看数据,50000,那么O(n)或者O(n log(n))是可以过的,非严格O(n * sqrt(n))要卡卡常,说不定也可以过. 那么什么算法可以 ...

  3. react-native修改xcode项目名

    目录 1. 选中旧工程名,改为新的工程名 2. 依次选择黄色文件夹,修改名字,千万不要在Xcode外修改!!! 3. 点击Find,点击Find and Replace in Project... 4 ...

  4. git 使用详解(2)——安装+配置+获取帮助

    安装 Git Git 有许多种安装方式,主要分为两种,一种是通过编译源代码来安装:另一种是使用为特定平台预编译好的安装包. 从源代码安装 若是条件允许,从源代码安装有很多好处,至少可以安装最新的版本. ...

  5. 无向图的桥+搜索优化--UESTC1956-北极的猴子

    北极的猴子 Time Limit: 1000 MS     Memory Limit: 256 MB Submit Status 也许你不知道,在北极也有猴子,我们叫它们北极猴.北极猴们在北极一共有n ...

  6. [vue]初探生命周期

    Vue 实例从创建到销毁的过程,就是生命周期.也就是从开始创建.初始化数据.编译模板.挂载Dom→渲染.更新→渲染.卸载等一系列过程,我们称这是 Vue 的生命周期. 一.创建/销毁,缓存 1.cre ...

  7. B树?这篇文章彻底看懂了!

    前言 索引,相信大多数人已经相当熟悉了,很多人都知道 MySQL 的索引主要以 B+ 树为主,但是要问到为什么用 B+ 树,恐怕很少有人能把前因后果讲述完整.本文就来从头到尾介绍下数据库的索引. 索引 ...

  8. [权限管理系统篇] (五)-Spring security(授权过程分析)

    欢迎关注公众号[Ccww笔记],原创技术文章第一时间推出 前言 权限管理系统的组件分析以及认证过程的往期文章: Spring security (一)架构框架-Component.Service.Fi ...

  9. 在 Windows 10 上搭建 Cordova 跨平台开发 Android 环境

    目录 安装 Cordova 安装 Java 和 Android 环境 创建 Cordova 应用程序 构建和运行 Cordova Cordova 简介:Cordova 原名 PhoneGap,是一个开 ...

  10. 【ES6基础】let、const命令和变量的结构赋值

    ES5声明变量(2):var .function ES6声明变量(6):var.function.let.const.import和class 1.let命令和const命令 (1)let和const ...