~ubuntu-branches/ubuntu/vivid/jayatana/vivid

« back to all changes in this revision

Viewing changes to libjayatanaag/com_jarego_jayatana_Agent.c

  • Committer: Package Import Robot
  • Author(s): Jared González
  • Date: 2014-12-10 17:38:15 UTC
  • Revision ID: package-import@ubuntu.com-20141210173815-8k4hm3bd481qkt63
Tags: upstream-2.7
Import upstream version 2.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2014 Jared González
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any
 
5
 * person obtaining a copy of this software and associated
 
6
 * documentation files (the "Software"), to deal in the
 
7
 * Software without restriction, including without limitation
 
8
 * the rights to use, copy, modify, merge, publish,
 
9
 * distribute, sublicense, and/or sell copies of the
 
10
 * Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice
 
14
 * shall be included in all copies or substantial portions of
 
15
 * the Software.
 
16
 *
 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 
18
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 
19
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
20
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 
21
 * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
22
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
25
 *
 
26
 * File:   com_jarego_jayatana_Agent.c
 
27
 * Author: Jared González
 
28
 */
 
29
#include <jvmti.h>
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include <unistd.h>
 
33
#include <string.h>
 
34
#include <X11/Xlib.h>
 
35
 
 
36
#include "com_jarego_jayatana_Agent.h"
 
37
 
 
38
/**
 
39
 * Inicializar observadores de componentes para prevenir la integración
 
40
 * con Ubuntu/Linux.
 
41
 */
 
42
jvmtiError com_jarego_jayatana_Initialize(JavaVM *vm, int fromAgent);
 
43
 
 
44
/**
 
45
 * Validar el valor de una variable de ambiente para más opciones o
 
46
 * variables de configuración.
 
47
 */
 
48
int com_jarego_jayatana_Agent_CheckEnv(const char *envname, const char *envval, const int def);
 
49
 
 
50
/**
 
51
 * Iniciar observador de inicio de hilos para prevenir la integración
 
52
 * con Ubuntu/Linux
 
53
 */
 
54
static void JNICALL
 
55
com_jarego_jayatana_Agent_threadStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread) {
 
56
        // recuperar información del hilo
 
57
        jvmtiError error;
 
58
        jvmtiThreadInfo info;
 
59
        error = (*jvmti_env)->GetThreadInfo(jvmti_env, thread, &info);
 
60
        if (error == JVMTI_ERROR_NONE) {
 
61
                // inicializar XInitThreads para corregir defecto en OpenJDK 6 para los hilos de AWT o
 
62
                // Java 2D
 
63
                if (strcmp(info.name, "Java2D Disposer") == 0) {
 
64
                        // inicializar hilos de X, solo para OpenJDK 6
 
65
                        char *version = 0;
 
66
                        if ((*jvmti_env)->GetSystemProperty(
 
67
                                        jvmti_env, "java.vm.specification.version", &version) == JVMTI_ERROR_NONE) {
 
68
                                if (strcmp(version, "1.0") == 0) {
 
69
                                        // TODO: Utilizando openjdk6, al actualizar el objeto
 
70
                                        // splashScreen (splashScreen.update) la aplicacion muere.
 
71
                                        // Existe un conflicto al utilizar XInitThread y pthread.
 
72
                                        // Error:
 
73
                                        //   java: pthread_mutex_lock.c:317: __pthread_mutex_lock_full: La declaración `(-(e)) != 3 || !robust' no se cumple.
 
74
                                        XInitThreads();
 
75
                                }
 
76
                                (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)version);
 
77
                        }
 
78
                } else if (strcmp(info.name, "AWT-XAWT") == 0) {
 
79
                        // instala la clase para control de integración Swing
 
80
                        jclass clsInstallers = (*jni_env)->FindClass(
 
81
                                        jni_env, "com/jarego/jayatana/FeatureManager");
 
82
                        if (clsInstallers != NULL) {
 
83
                                jmethodID midInstallForSwing = (*jni_env)->GetStaticMethodID(
 
84
                                                jni_env, clsInstallers, "deployForSwing", "()V");
 
85
                                (*jni_env)->CallStaticVoidMethod(jni_env, clsInstallers, midInstallForSwing);
 
86
                                (*jni_env)->DeleteLocalRef(jni_env, clsInstallers);
 
87
                        }
 
88
                        // una vez inicializada la prueba
 
89
                        (*jvmti_env)->SetEventNotificationMode(jvmti_env,
 
90
                                JVMTI_DISABLE, JVMTI_EVENT_THREAD_START, (jthread)NULL);
 
91
                }
 
92
        }
 
93
}
 
94
 
 
95
/**
 
96
 * Cargar agente para integración con Ubuntu/Linux
 
97
 */
 
98
JNIEXPORT jint JNICALL
 
99
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
 
100
        return com_jarego_jayatana_Initialize(vm, 1);
 
101
}
 
102
 
 
103
/**
 
104
 * Carga libreria nativa desde agente Java para integración
 
105
 * con Ubuntu/Linux
 
106
 */
 
107
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
 
108
        com_jarego_jayatana_Initialize(vm, 0);
 
109
        return JNI_VERSION_1_6;
 
110
}
 
111
 
 
112
/**
 
113
 * Inicializar observadores de componentes para prevenir la integración
 
114
 * con Ubuntu/Linux.
 
115
 */
 
116
jvmtiError com_jarego_jayatana_Initialize(JavaVM *vm, int fromAgent) {
 
117
        // en caso de no exista una referencia a jayatana
 
118
        if (getenv("JAYATANA_CLASSPATH") == NULL &&
 
119
                        access("/usr/share/java/jayatana.jar", R_OK) != 0)
 
120
                return JVMTI_ERROR_NONE;
 
121
 
 
122
        // la librería si existe iniciar procedo de validación de integración
 
123
        if (com_jarego_jayatana_Agent_CheckEnv("XDG_CURRENT_DESKTOP", "Unity", False) ?
 
124
                        com_jarego_jayatana_Agent_CheckEnv("JAYATANA_FORCE", "true", True) &&
 
125
                        com_jarego_jayatana_Agent_CheckEnv("JAYATANA", "1", True) :
 
126
                        com_jarego_jayatana_Agent_CheckEnv("JAYATANA_FORCE", "true", False) ||
 
127
                        com_jarego_jayatana_Agent_CheckEnv("JAYATANA", "1", False)) {
 
128
 
 
129
                // inicializar entorno
 
130
                jvmtiEnv *jvmti_env;
 
131
                (*vm)->GetEnv(vm, (void**) &jvmti_env, JVMTI_VERSION);
 
132
 
 
133
                // recuperar version
 
134
                char *version = 0;
 
135
                if ((*jvmti_env)->GetSystemProperty(
 
136
                                jvmti_env, "java.vm.version", &version) == JVMTI_ERROR_NONE) {
 
137
 
 
138
                        // ignorar para versiones 1.4 y 1.5
 
139
                        if (strncmp(version, "1.4", 3) != 0 && strncmp(version, "1.5", 3) != 0) {
 
140
 
 
141
                                // activar capacidades
 
142
                                jvmtiCapabilities capabilities;
 
143
                                memset(&capabilities, 0, sizeof(jvmtiCapabilities));
 
144
                                //capabilities.can_generate_method_exit_events = 1;
 
145
                                (*jvmti_env)->AddCapabilities(jvmti_env, &capabilities);
 
146
 
 
147
                                // registrar funciones de eventos
 
148
                                jvmtiEventCallbacks callbacks;
 
149
                                memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
 
150
                                //callbacks.MethodExit = &com_jarego_jayatana_Agent_MethodExit;
 
151
                                callbacks.ThreadStart = &com_jarego_jayatana_Agent_threadStart;
 
152
                                (*jvmti_env)->SetEventCallbacks(jvmti_env,
 
153
                                                &callbacks, (jint)sizeof(jvmtiEventCallbacks));
 
154
 
 
155
                                // habilitar gestor de eventos
 
156
                                (*jvmti_env)->SetEventNotificationMode(jvmti_env,
 
157
                                                JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, (jthread)NULL);
 
158
                                //(*jvmti_env)->SetEventNotificationMode(jvmti_env,
 
159
                                //              JVMTI_ENABLE, JVMTI_EVENT_METHOD_EXIT, (jthread)NULL);
 
160
 
 
161
                                // cargar ruta de clases jayatana
 
162
                                if (getenv("JAYATANA_CLASSPATH") != NULL) {// opción para desarrollo
 
163
                                        (*jvmti_env)->AddToSystemClassLoaderSearch(
 
164
                                                        jvmti_env, getenv("JAYATANA_CLASSPATH"));
 
165
                                        fprintf(stderr, "JAYATANA_CLASSPATH=%s\n", getenv("JAYATANA_CLASSPATH"));
 
166
                                } else {
 
167
                                        (*jvmti_env)->AddToSystemClassLoaderSearch(
 
168
                                                        jvmti_env, "/usr/share/java/jayatana.jar");
 
169
                                }
 
170
                        }
 
171
 
 
172
                        // liberar cadena de versión
 
173
                        (*jvmti_env)->Deallocate(jvmti_env, (unsigned char*)version);
 
174
                }
 
175
        }
 
176
        return JVMTI_ERROR_NONE;
 
177
}
 
178
 
 
179
/**
 
180
 * Validar el valor de una variable de ambiente para más opciones o
 
181
 * variables de configuración.
 
182
 */
 
183
int com_jarego_jayatana_Agent_CheckEnv(const char *envname, const char *envval, const int def) {
 
184
        if (getenv(envname) == NULL) return def;
 
185
        else if (strcmp(getenv(envname), envval) == 0) return True;
 
186
        else return False;
 
187
}
 
188