修改前

修改后

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. springboot-整合多数据源配置

    简介 主要介绍两种整合方式,分别是 springboot+mybatis 使用分包方式整合,和 springboot+druid+mybatisplus 使用注解方式整合. 一.表结构 在本地新建两个 ...

  2. 3D硬件加速提升动画性能 与 z-index属性

    目录 1. chrome Layer borders 2. 层创建标准 3. 例子 总结 1. chrome Layer borders <WebKit技术内幕>第二章介绍了网页的结构,其 ...

  3. aplipay支付-app支付之前后端实现

    目录 前言 一 前台aplipay实现 1.1 安装0x5e/react-native-alipay 1.2. 配置 1.3. Alipay.pay(orderStr) 二 后端 2.1 服务端sdk ...

  4. UESTC-1975弗吉桑(回文串,manacher算法)

    弗吉桑 Time Limit: 3000 MS     Memory Limit: 64 MB Submit Status 弗吉桑是一座横跨清水河大草原的活火山,位于子科技大学主楼东北方约 80km ...

  5. Python必学之编译器用哪个好?你用错了吧!

    学python要知道怎么用好编译器.当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件由于整个Pyth ...

  6. Win32_PhysicalMedia 硬盘 参数说明

    Caption 物理内存还虚拟内存 Description 描述和Caption一样 InstallDate 安装日期(无值) Name 名字 Status 状态 CreationClassName ...

  7. 计算密集型和 io 密集型项目的使用场景分析和代码演示

    from threading import Thread from multiprocessing import Process import time 计算密集型 def work1(): res= ...

  8. Java设计模式整理

    一.创建型模式 1.抽象工厂模式(AbstractFactory): 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要指定具体类. 案例:https://www.cnblogs.com/lfx ...

  9. 第三次作业-Python网络爬虫与信息提取

    1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 过程. 5.写一篇不少于100 ...

  10. LImax服务器框架学习--安装、使用ant工具、生成limax相关代码

    一.安装ant ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.在实际软件开发中,有很多地方可以用到ant. 首先现在一个ant安装压缩包, ...