c26620ccbf2ca6586d984c100e5aa8f04b769728
[blender-staging.git] / source / blender / src / space.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  *
30  * - here initialize and free and handling SPACE data
31  */
32
33 #include <string.h>
34 #include <stdio.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include "MEM_guardedalloc.h"
41 #include "MEM_CacheLimiterC-Api.h"
42
43 #ifdef INTERNATIONAL
44 #include "BIF_language.h"
45 #endif
46
47 #include "IMB_imbuf_types.h"
48 #include "IMB_imbuf.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_gsqueue.h"
53 #include "BLI_linklist.h"
54
55 #include "DNA_action_types.h"
56 #include "DNA_armature_types.h"
57 #include "DNA_curve_types.h"
58 #include "DNA_group_types.h" /* used for select_same_group */
59 #include "DNA_gpencil_types.h"
60 #include "DNA_image_types.h"
61 #include "DNA_ipo_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_modifier_types.h" /* used for select grouped hooks */
65 #include "DNA_object_types.h"
66 #include "DNA_particle_types.h"
67 #include "DNA_property_types.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_screen_types.h"
70 #include "DNA_sequence_types.h"
71 #include "DNA_sound_types.h"
72 #include "DNA_space_types.h"
73 #include "DNA_userdef_types.h"
74 #include "DNA_view2d_types.h"
75 #include "DNA_view3d_types.h"
76
77 #include "BKE_blender.h"
78 #include "BKE_colortools.h"
79 #include "BKE_curve.h"
80 #include "BKE_depsgraph.h"
81 #include "BKE_DerivedMesh.h"
82 #include "BKE_displist.h"
83 #include "BKE_global.h"
84 #include "BKE_group.h"
85 #include "BKE_ipo.h"
86 #include "BKE_main.h"
87 #include "BKE_mesh.h"
88 #include "BKE_multires.h"
89 #include "BKE_node.h"
90 #include "BKE_pointcache.h"
91 #include "BKE_property.h"
92 #include "BKE_scene.h"
93 #include "BKE_sculpt.h"
94 #include "BKE_texture.h"
95 #include "BKE_utildefines.h"
96 #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
97 #include "BKE_particle.h"
98 #include "BIF_spacetypes.h"  /* first, nasty dependency with typedef */
99
100 #include "BIF_butspace.h"
101 #include "BIF_drawimage.h"
102 #include "BIF_drawseq.h"
103 #include "BIF_drawtext.h"
104 #include "BIF_drawscript.h"
105 #include "BIF_editarmature.h"
106 #include "BIF_editparticle.h"
107 #include "BIF_editconstraint.h"
108 #include "BIF_editdeform.h"
109 #include "BIF_editfont.h"
110 #include "BIF_editgroup.h"
111 #include "BIF_editkey.h"
112 #include "BIF_editlattice.h"
113 #include "BIF_editmesh.h"
114 #include "BIF_editmode_undo.h"
115 #include "BIF_editnla.h"
116 #include "BIF_editoops.h"
117 #include "BIF_editseq.h"
118 #include "BIF_editsima.h"
119 #include "BIF_editsound.h"
120 #include "BIF_editview.h"
121 #include "BIF_filelist.h"
122 #include "BIF_gl.h"
123 #include "BIF_imasel.h"
124 #include "BIF_interface.h"
125 #include "BIF_interface_icons.h"
126 #include "BIF_keyframing.h"
127 #include "BIF_meshtools.h"
128 #include "BIF_mywindow.h"
129 #include "BIF_oops.h"
130 #include "BIF_poselib.h"
131 #include "BIF_poseobject.h"
132 #include "BIF_outliner.h"
133 #include "BIF_radialcontrol.h"
134 #include "BIF_resources.h"
135 #include "BIF_retopo.h"
136 #include "BIF_screen.h"
137 #include "BIF_space.h"
138 #include "BIF_toets.h"
139 #include "BIF_toolbox.h"
140 #include "BIF_usiblender.h"
141 #include "BIF_previewrender.h"
142
143 #include "BSE_edit.h"
144 #include "BSE_view.h"
145 #include "BSE_editipo.h"
146 #include "BSE_drawipo.h"
147 #include "BSE_drawview.h"
148 #include "BSE_drawnla.h"
149 #include "BSE_filesel.h"
150 #include "BSE_headerbuttons.h"
151 #include "BSE_editnla_types.h"
152 #include "BSE_time.h"
153 #include "BSE_trans_types.h"
154
155 #include "BDR_vpaint.h"
156 #include "BDR_editmball.h"
157 #include "BDR_editobject.h"
158 #include "BDR_editcurve.h"
159 #include "BDR_editface.h"
160 #include "BDR_drawmesh.h"
161 #include "BDR_drawobject.h"
162 #include "BDR_imagepaint.h"
163 #include "BDR_sculptmode.h"
164 #include "BDR_unwrapper.h"
165 #include "BDR_gpencil.h"
166
167 #include "BLO_readfile.h" /* for BLO_blendhandle_close */
168
169 #include "PIL_time.h"
170
171 #include "BPY_extern.h"
172
173 #include "butspace.h"
174 #include "mydevice.h"
175 #include "blendef.h"
176 #include "datatoc.h"
177 #include "multires.h"
178
179 #include "BIF_transform.h"
180
181 #include "BKE_depsgraph.h"
182
183 #include "BSE_trans_types.h"
184
185 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
186
187 #include "GPU_extensions.h"
188 #include "GPU_draw.h"
189
190 #include "BLO_sys_types.h" // for intptr_t support
191
192 /* maybe we need this defined somewhere else */
193 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
194 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);/*rcruiz*/
195
196 /**
197  * When the mipmap setting changes, we want to redraw the view right
198  * away to reflect this setting.
199  */
200 //static void space_mipmap_button_function(int event);
201
202 static void free_soundspace(SpaceSound *ssound);
203
204 /* *************************************** */
205
206 /* don't know yet how the handlers will evolve, for simplicity
207    i choose for an array with eventcodes, this saves in a file!
208    */
209 void add_blockhandler(ScrArea *sa, short eventcode, short val)
210 {
211         SpaceLink *sl= sa->spacedata.first;
212         short a;
213         
214         /* find empty spot */
215         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
216                 if( sl->blockhandler[a]==eventcode ) {
217                         sl->blockhandler[a+1]= val;
218                         break;
219                 }
220                 else if( sl->blockhandler[a]==0) {
221                         sl->blockhandler[a]= eventcode;
222                         sl->blockhandler[a+1]= val;
223                         break;
224                 }
225         }
226         if(a==SPACE_MAXHANDLER) {
227                 error("Only %i floating panels allowed", SPACE_MAXHANDLER/2);
228         }
229                 
230 }
231
232 void rem_blockhandler(ScrArea *sa, short eventcode)
233 {
234         SpaceLink *sl= sa->spacedata.first;
235         short a;
236         
237         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
238                 if( sl->blockhandler[a]==eventcode) {
239                         sl->blockhandler[a]= 0;
240                         
241                         /* specific free calls */
242                         if(eventcode==IMAGE_HANDLER_PREVIEW)
243                                 image_preview_event(0);
244                         break;
245                 }
246         }
247 }
248
249 void toggle_blockhandler(ScrArea *sa, short eventcode, short val)
250 {
251         SpaceLink *sl= sa->spacedata.first;
252         short a, addnew=1;
253         
254         /* find if it exists */
255         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
256                 if( sl->blockhandler[a]==eventcode ) {
257                         sl->blockhandler[a]= 0;
258                         
259                         /* specific free calls */
260                         if(eventcode==VIEW3D_HANDLER_PREVIEW)
261                                 BIF_view3d_previewrender_free(sa->spacedata.first);
262                         else if(eventcode==IMAGE_HANDLER_PREVIEW)
263                                 image_preview_event(0);
264                         
265                         addnew= 0;
266                 }
267         }
268         if(addnew) {
269                 add_blockhandler(sa, eventcode, val);
270                 
271                 /* specific add new calls */
272                 if(eventcode==IMAGE_HANDLER_PREVIEW)
273                         image_preview_event(1);
274         }
275 }
276
277
278
279 /* ************* SPACE: VIEW3D  ************* */
280
281 /*  extern void drawview3dspace(ScrArea *sa, void *spacedata); BSE_drawview.h */
282
283
284 void copy_view3d_lock(short val)
285 {
286         bScreen *sc;
287         int bit;
288         
289         /* from G.scene copy to the other views */
290         sc= G.main->screen.first;
291         
292         while(sc) {
293                 if(sc->scene==G.scene) {
294                         ScrArea *sa= sc->areabase.first;
295                         while(sa) {
296                                 SpaceLink *sl= sa->spacedata.first;
297                                 while(sl) {
298                                         if(sl->spacetype==SPACE_OOPS && val==REDRAW) {
299                                                 if(sa->win) scrarea_queue_winredraw(sa);
300                                         }
301                                         else if(sl->spacetype==SPACE_VIEW3D) {
302                                                 View3D *vd= (View3D*) sl;
303                                                 if(vd->scenelock && vd->localview==0) {
304                                                         vd->lay= G.scene->lay;
305                                                         vd->camera= G.scene->camera;
306                                                         
307                                                         if(vd->camera==0 && vd->persp==V3D_CAMOB) vd->persp= V3D_PERSP;
308                                                         
309                                                         if( (vd->lay & vd->layact) == 0) {
310                                                                 bit= 0;
311                                                                 while(bit<32) {
312                                                                         if(vd->lay & (1<<bit)) {
313                                                                                 vd->layact= 1<<bit;
314                                                                                 break;
315                                                                         }
316                                                                         bit++;
317                                                                 }
318                                                         }
319                                                         
320                                                         if(val==REDRAW && vd==sa->spacedata.first) {
321                                                                 if(sa->win) scrarea_queue_redraw(sa);
322                                                         }
323                                                 }
324                                         }
325                                         sl= sl->next;
326                                 }
327                                 sa= sa->next;
328                         }
329                 }
330                 sc= sc->id.next;
331         }
332 }
333
334 void handle_view3d_around()
335 {
336         bScreen *sc;
337         
338         if ((U.uiflag & USER_LOCKAROUND)==0) return;
339         
340         /* copies from G.vd->around to other view3ds */
341         
342         sc= G.main->screen.first;
343         
344         while(sc) {
345                 if(sc->scene==G.scene) {
346                         ScrArea *sa= sc->areabase.first;
347                         while(sa) {
348                                 SpaceLink *sl= sa->spacedata.first;
349                                 while(sl) {
350                                         if(sl->spacetype==SPACE_VIEW3D) {
351                                                 View3D *vd= (View3D*) sl;
352                                                 if (vd != G.vd) {
353                                                         vd->around= G.vd->around;
354                                                         if (G.vd->flag & V3D_ALIGN)
355                                                                 vd->flag |= V3D_ALIGN;
356                                                         else
357                                                                 vd->flag &= ~V3D_ALIGN;
358                                                         scrarea_queue_headredraw(sa);
359                                                 }
360                                         }
361                                         sl= sl->next;
362                                 }
363                                 sa= sa->next;
364                         }
365                 }
366                 sc= sc->id.next;
367         }
368 }
369
370 void handle_view3d_lock()
371 {       
372         if (G.vd != NULL && curarea != NULL ) {
373                 if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) {
374
375                         /* copy to scene */
376                         G.scene->lay= G.vd->lay;
377                         G.scene->camera= G.vd->camera;
378         
379                         copy_view3d_lock(REDRAW);
380                 }
381         }
382 }
383
384 void space_set_commmandline_options(void) {
385         SYS_SystemHandle syshandle;
386         int a;
387                 
388         if ( (syshandle = SYS_GetSystem()) ) {
389                 /* User defined settings */
390                 a= (U.gameflags & USER_DISABLE_SOUND);
391                 /* if user already disabled audio at the command-line, don't re-enable it */
392                 if (a)
393                 {
394                         SYS_WriteCommandLineInt(syshandle, "noaudio", a);
395                 }
396
397                 a= (U.gameflags & USER_DISABLE_MIPMAP);
398                 GPU_set_mipmap(!a);
399                 SYS_WriteCommandLineInt(syshandle, "nomipmap", a);
400
401                 /* File specific settings: */
402                 /* Only test the first one. These two are switched
403                  * simultaneously. */
404                 a= (G.fileflags & G_FILE_SHOW_FRAMERATE);
405                 SYS_WriteCommandLineInt(syshandle, "show_framerate", a);
406                 SYS_WriteCommandLineInt(syshandle, "show_profile", a);
407
408                 /* When in wireframe mode, always draw debug props. */
409                 if (G.vd) {
410                         a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS) 
411                                   || (G.vd->drawtype == OB_WIRE)          
412                                   || (G.vd->drawtype == OB_SOLID)         );
413                         SYS_WriteCommandLineInt(syshandle, "show_properties", a);
414                 }
415                 
416                 a= (G.fileflags & G_FILE_SHOW_PHYSICS);
417                 SYS_WriteCommandLineInt(syshandle, "show_physics", a);
418
419                 a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES);
420                 SYS_WriteCommandLineInt(syshandle, "fixedtime", a);
421
422                 a= (G.fileflags & G_FILE_GAME_TO_IPO);
423                 SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
424
425                 a=(G.fileflags & G_FILE_GAME_MAT);
426                 SYS_WriteCommandLineInt(syshandle, "blender_material", a);
427                 a=(G.fileflags & G_FILE_GAME_MAT_GLSL);
428                 SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", a);
429                 a=(G.fileflags & G_FILE_DISPLAY_LISTS);
430                 SYS_WriteCommandLineInt(syshandle, "displaylists", a);
431
432
433         }
434 }
435
436 #if GAMEBLENDER == 1
437         /**
438          * These two routines imported from the gameengine, 
439          * I suspect a lot of the resetting stuff is cruft
440          * and can be removed, but it should be checked.
441          */
442 static void SaveState(void)
443 {
444         glPushAttrib(GL_ALL_ATTRIB_BITS);
445
446         GPU_state_init();
447
448         if(G.f & G_TEXTUREPAINT)
449                 GPU_paint_set_mipmap(1);
450
451         waitcursor(1);
452 }
453
454 static void RestoreState(void)
455 {
456         if(G.f & G_TEXTUREPAINT)
457                 GPU_paint_set_mipmap(0);
458
459         curarea->win_swap = 0;
460         curarea->head_swap=0;
461         allqueue(REDRAWVIEW3D, 1);
462         allqueue(REDRAWBUTSALL, 0);
463         reset_slowparents();
464         waitcursor(0);
465         G.qual= 0;
466         glPopAttrib();
467 }
468
469 static LinkNode *save_and_reset_all_scene_cfra(void)
470 {
471         LinkNode *storelist= NULL;
472         Scene *sc;
473         
474         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
475                 BLI_linklist_prepend(&storelist, (void*) (intptr_t) sc->r.cfra);
476
477                 /* why is this reset to 1 ?*/
478                 /* sc->r.cfra= 1;*/
479
480                 set_scene_bg(sc);
481         }
482         
483         BLI_linklist_reverse(&storelist);
484         
485         return storelist;
486 }
487
488 static void restore_all_scene_cfra(LinkNode *storelist) {
489         LinkNode *sc_store= storelist;
490         Scene *sc;
491         
492         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
493                 int stored_cfra= (intptr_t) sc_store->link;
494                 
495                 sc->r.cfra= stored_cfra;
496                 set_scene_bg(sc);
497                 
498                 sc_store= sc_store->next;
499         }
500         
501         BLI_linklist_free(storelist, NULL);
502 }
503 #endif
504
505 void start_game(void)
506 {
507 #if GAMEBLENDER == 1
508 #ifndef NO_KETSJI
509         Scene *sc, *startscene = G.scene;
510         LinkNode *scene_cfra_store;
511
512                 /* XXX, silly code -  the game engine can
513                  * access any scene through logic, so we try 
514                  * to make sure each scene has a valid camera, 
515                  * just in case the game engine tries to use it.
516                  * 
517                  * Better would be to make a better routine
518                  * in the game engine for finding the camera.
519                  *  - zr
520                  * Note: yes, this is all very badly hacked! (ton)
521                  */
522         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
523                 if (!sc->camera) {
524                         Base *base;
525         
526                         for (base= sc->base.first; base; base= base->next)
527                                 if (base->object->type==OB_CAMERA)
528                                         break;
529                         
530                         sc->camera= base?base->object:NULL;
531                 }
532         }
533
534         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
535         markdirty_all();
536         screen_swapbuffers();
537
538         /* can start from header */
539         mywinset(curarea->win);
540     
541         scene_cfra_store= save_and_reset_all_scene_cfra();
542         
543
544         /* game engine will do its own sounds. */
545         sound_stop_all_sounds();
546         sound_exit_audio();
547         
548         /* Before jumping into Ketsji, we configure some settings. */
549         space_set_commmandline_options();
550
551         SaveState();
552         StartKetsjiShell(curarea, startscene->id.name+2, G.main,G.sipo, 1);
553         RestoreState();
554
555         /* Restart BPY - unload the game engine modules. */
556
557         /* Commented out: testing before Blender 2.46 if it's ok to keep
558          * these modules around, they give access to relevant info for
559          * exporters to other engines...
560         BPY_end_python();
561         BPY_start_python(0, NULL); 
562         BPY_post_start_python();
563         */
564
565         restore_all_scene_cfra(scene_cfra_store);
566         set_scene_bg(startscene);
567         scene_update_for_newframe(G.scene, G.scene->lay);
568
569         if (G.flags & G_FILE_AUTOPLAY)
570                 exit_usiblender();
571
572                 /* groups could have changed ipo */
573         allqueue(REDRAWNLA, 0);
574         allqueue(REDRAWACTION, 0);
575         allspace(REMAKEIPO, 0);
576         allqueue(REDRAWIPO, 0);
577 #endif
578 #else
579         notice("Game engine is disabled in this release!");
580 #endif
581 }
582
583 void start_RBSimulation(void)
584 {
585 #if GAMEBLENDER == 1
586 #ifndef NO_KETSJI
587         Scene *sc, *startscene = G.scene;
588         LinkNode *scene_cfra_store;
589
590                 /* XXX, silly code -  the game engine can
591                  * access any scene through logic, so we try
592                  * to make sure each scene has a valid camera,
593                  * just in case the game engine tries to use it.
594                  *
595                  * Better would be to make a better routine
596                  * in the game engine for finding the camera.
597                  *  - zr
598                  * Note: yes, this is all very badly hacked! (ton)
599                  */
600         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
601                 if (!sc->camera) {
602                         Base *base;
603
604                         for (base= sc->base.first; base; base= base->next)
605                                 if (base->object->type==OB_CAMERA)
606                                         break;
607
608                         sc->camera= base?base->object:NULL;
609                 }
610         }
611
612         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
613         markdirty_all();
614         screen_swapbuffers();
615
616         /* can start from header */
617         mywinset(curarea->win);
618
619         scene_cfra_store= save_and_reset_all_scene_cfra();
620
621
622         /* game engine will do its own sounds. */
623         sound_stop_all_sounds();
624         sound_exit_audio();
625
626         /* Before jumping into Ketsji, we configure some settings. */
627         space_set_commmandline_options();
628
629         SaveState();
630         StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
631         RestoreState();
632
633         /* Restart BPY - unload the game engine modules. */
634
635         /* Commented out: testing before Blender 2.46 if it's ok to keep
636          * these modules around, they give access to relevant info for
637          * exporters to other engines...
638         BPY_end_python();
639         BPY_start_python(0, NULL); 
640         BPY_post_start_python();
641         */
642
643         restore_all_scene_cfra(scene_cfra_store);
644         set_scene_bg(startscene);
645         scene_update_for_newframe(G.scene, G.scene->lay);
646
647         if (G.flags & G_FILE_AUTOPLAY)
648                 exit_usiblender();
649
650                 /* groups could have changed ipo */
651         allqueue(REDRAWNLA, 0);
652         allqueue(REDRAWACTION, 0);
653         allspace(REMAKEIPO, 0);
654         allqueue(REDRAWIPO, 0);
655 #endif
656 #else
657         notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!");
658 #endif
659 }
660
661 static void changeview3dspace(ScrArea *sa, void *spacedata)
662 {
663         setwinmatrixview3d(sa->winx, sa->winy, NULL);   /* 0= no pick rect */
664 }
665
666         /* Callable from editmode and faceselect mode from the
667          * moment, would be nice (and is easy) to generalize
668          * to any mode.
669          */
670 static void align_view_to_selected(View3D *v3d)
671 {
672         int nr= pupmenu("Align View (Ctrl flips)%t|To Selected (top)%x3|To Selected (front)%x2|To Selected (side)%x1");
673         if (nr!=-1) {
674                 int axis= nr;
675                 
676                 /* opposite axis in case ctrl is pressed */
677                 if(G.qual==LR_CTRLKEY) axis= -axis;
678                 
679                 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
680                         editmesh_align_view_to_selected(v3d, axis);
681                         addqueue(v3d->area->win, REDRAW, 1);
682                 } else if (FACESEL_PAINT_TEST) {
683                         Object *obact= OBACT;
684                         if (obact && obact->type==OB_MESH) {
685                                 Mesh *me= obact->data;
686                                 faceselect_align_view_to_selected(v3d, me, axis);
687                                 addqueue(v3d->area->win, REDRAW, 1);
688                         }
689                 }
690         }
691 }
692
693
694 static short select_children(Object *ob, int recursive)
695 {
696         short changed = 0;
697         Base *base;
698         
699         for (base= FIRSTBASE; base; base= base->next) {
700                 if (ob == base->object->parent) {
701                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT)) {
702                                 base->flag |= SELECT;
703                                 base->object->flag |= SELECT;
704                                 changed = 1;
705                         }
706                         
707                         if (recursive)
708                                 changed |= select_children(base->object, 1);
709                 }
710         }
711         return changed;
712 }
713
714 static short select_parent(void)        /* Makes parent active and de-selected OBACT */
715 {
716         short changed = 0;
717         Base *base, *startbase, *basact=NULL, *oldbasact;
718         
719         if (!(OBACT->parent)) return 0; /* we know OBACT is valid */
720         BASACT->flag &= (~SELECT);
721         BASACT->object->flag &= (~SELECT);
722         startbase=  FIRSTBASE;
723         if(BASACT && BASACT->next) startbase= BASACT->next;
724         base = startbase;
725         while(base) {
726                 if(base->object==BASACT->object->parent) { basact=base; break; }
727                 base=base->next;
728                 if(base==NULL) base= FIRSTBASE;
729                 if(base==startbase) break;
730         }
731         /* can be NULL if parent in other scene */
732         if(basact && BASE_SELECTABLE(basact)) {
733                 oldbasact = BASACT;
734                 BASACT = basact;
735                 basact->flag |= SELECT;         
736                 
737                 basact->object->flag= basact->flag;
738                 
739                 set_active_base(basact);
740                 changed = 1;
741         }
742         return changed;
743 }
744
745
746 #define GROUP_MENU_MAX  24
747 static short select_same_group(Object *ob)      /* Select objects in the same group as the active */
748 {
749         short changed = 0;
750         Base *base;
751         Group *group, *ob_groups[GROUP_MENU_MAX];
752         char str[10 + (24*GROUP_MENU_MAX)];
753         char *p = str;
754         int group_count=0, menu, i;
755         
756         for (   group=G.main->group.first;
757                         group && group_count < GROUP_MENU_MAX;
758                         group=group->id.next
759                 ) {
760                 if (object_in_group (ob, group)) {
761                         ob_groups[group_count] = group;
762                         group_count++;
763                 }
764         }
765         
766         if (!group_count)
767                 return 0;
768         
769         else if (group_count == 1) {
770                 group = ob_groups[0];
771                 for (base= FIRSTBASE; base; base= base->next) {
772                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && object_in_group(base->object, group)) {
773                                 base->flag |= SELECT;
774                                 base->object->flag |= SELECT;
775                                 changed = 1;
776                         }
777                 }
778                 return changed;
779         }
780         
781         /* build the menu. */
782         p += sprintf(str, "Groups%%t"); 
783         for (i=0; i<group_count; i++) {
784                 group = ob_groups[i];
785                 p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
786         }
787         
788         menu = pupmenu (str);
789         if (menu == -1)
790                 return 0;
791         
792         group = ob_groups[menu];
793         for (base= FIRSTBASE; base; base= base->next) {
794                 if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
795                         base->flag |= SELECT;
796                         base->object->flag |= SELECT;
797                         changed = 1;
798                 }
799         }
800         return changed;
801 }
802
803 static short select_object_hooks(Object *ob)
804 {
805         short changed = 0;
806         Base *base;
807         ModifierData *md;
808         HookModifierData *hmd;
809         
810         for (md = ob->modifiers.first; md; md=md->next) {
811                 if (md->type==eModifierType_Hook) {
812                         hmd= (HookModifierData*) md;
813                         if (hmd->object && !(hmd->object->flag & SELECT)) {
814                                 base= object_in_scene(hmd->object, G.scene);
815                                 if (base && BASE_SELECTABLE(base)) {
816                                         base->flag |= SELECT;
817                                         base->object->flag |= SELECT;
818                                         changed = 1;
819                                 }
820                         }
821                 }
822         }
823         return changed;
824 }
825
826 /* Select objects woth the same parent as the active (siblings),
827  * parent can be NULL also */
828 static short select_same_parent(Object *ob)     
829 {
830         short changed = 0;
831         Base *base;
832         
833         for (base= FIRSTBASE; base; base= base->next) {
834                 if (BASE_SELECTABLE(base) && (base->object->parent==ob->parent)  && !(base->flag & SELECT)) {
835                         base->flag |= SELECT;
836                         base->object->flag |= SELECT;
837                         changed = 1;
838                 }
839         }
840         return changed;
841 }
842
843 static short select_same_type(Object *ob)
844 {
845         short changed = 0;
846         Base *base;
847         
848         for (base= FIRSTBASE; base; base= base->next) {
849                 if (BASE_SELECTABLE(base) && (base->object->type == ob->type) && !(base->flag & SELECT)) {
850                         base->flag |= SELECT;
851                         base->object->flag |= SELECT;
852                         changed = 1;
853                 }
854         }
855         return changed;
856 }
857
858 static short select_same_layer(Object *ob)
859 {
860         char changed = 0;
861         Base *base = FIRSTBASE;
862         
863         while(base) {
864                 if (BASE_SELECTABLE(base) && (base->lay & ob->lay) && !(base->flag & SELECT)) {
865                         base->flag |= SELECT;
866                         base->object->flag |= SELECT;
867                         changed = 1;
868                 }
869                 base= base->next;
870         }
871         return changed;
872 }
873
874 static short select_same_index_object(Object *ob)
875 {
876         char changed = 0;
877         Base *base = FIRSTBASE;
878         
879         while(base) {
880                 if (BASE_SELECTABLE(base) && (base->object->index == ob->index) && !(base->flag & SELECT)) {
881                         base->flag |= SELECT;
882                         base->object->flag |= SELECT;
883                         changed = 1;
884                 }
885                 base= base->next;
886         }
887         return changed;
888 }
889
890 static short select_same_color(Object *ob)
891 {
892         char changed = 0;
893         Base *base = FIRSTBASE;
894         
895         while(base) {
896                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005f))) {
897                         base->flag |= SELECT;
898                         base->object->flag |= SELECT;
899                         changed = 1;
900                 }
901                 base= base->next;
902         }
903         return changed;
904 }
905
906 static short objects_share_gameprop(Object *a, Object *b)
907 {
908         bProperty *prop;
909         /*make a copy of all its properties*/
910         
911         for( prop= a->prop.first; prop; prop = prop->next ) {
912                 if ( get_ob_property(b, prop->name) )
913                         return 1;
914         }
915         return 0;
916 }
917
918 static short select_same_gameprops(Object *ob)
919 {
920         char changed = 0;
921         Base *base = FIRSTBASE;
922         
923         while(base) {
924                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
925                         base->flag |= SELECT;
926                         base->object->flag |= SELECT;
927                         changed = 1;
928                 }
929                 base= base->next;
930         }
931         return changed;
932 }
933
934 void select_object_grouped(short nr)
935 {
936         Object *ob = OBACT;
937         short changed = 0;
938         
939         if (ob==NULL) return;
940         
941         if(nr==1)               changed = select_children(ob, 1);
942         else if(nr==2)  changed = select_children(ob, 0);
943         else if(nr==3)  changed = select_parent();
944         else if(nr==4)  changed = select_same_parent(ob);       
945         else if(nr==5)  changed = select_same_type(ob);
946         else if(nr==6)  changed = select_same_layer(ob);        
947         else if(nr==7)  changed = select_same_group(ob);
948         else if(nr==8)  changed = select_object_hooks(ob);
949         else if(nr==9)  changed = select_same_index_object(ob);
950         else if(nr==10) changed = select_same_color(ob);
951         else if(nr==11) changed = select_same_gameprops(ob);
952         
953         if (changed) {
954                 countall();
955                 allqueue(REDRAWVIEW3D, 0);
956                 allqueue(REDRAWBUTSOBJECT, 0);
957                 allspace(REMAKEIPO, 0);
958                 allqueue(REDRAWIPO, 0);
959                 BIF_undo_push("Select Grouped");
960         }
961 }
962
963 static void select_object_grouped_menu(void)
964 {
965         char *str;
966         short nr;
967
968         /* make menu string */
969         
970         str= MEM_mallocN(512, "groupmenu");
971         strcpy(str, "Select Grouped%t|Children%x1|"
972                     "Immediate Children%x2|Parent%x3|"
973                     "Siblings (Shared Parent)%x4|"
974                     "Objects of Same Type%x5|"
975                                 "Objects on Shared Layers%x6|"
976                 "Objects in Same Group%x7|"
977                 "Object Hooks%x8|"
978                                 "Object PassIndex%x9|"
979                                 "Object Color%x10|"
980                                 "Game Properties%x11");
981
982         /* here we go */
983         
984         nr= pupmenu(str);
985         MEM_freeN(str);
986         
987         select_object_grouped(nr);
988 }
989
990 void join_menu(void)
991 {
992         Object *ob= OBACT;
993         if (G.obedit) {
994                 error("This data does not support joining in editmode");
995                 return;
996         }
997         if (!ob) {
998                 error("Can't join unless there is an active object");
999                 return;
1000         }
1001         
1002         if(ob->type == OB_MESH) {
1003                 if(okee("Join selected meshes")==0) return;
1004                 join_mesh();
1005         } else if(ob->type == OB_CURVE) {
1006                 if(okee("Join selected curves")==0) return;
1007                 join_curve(OB_CURVE);
1008         } else if(ob->type == OB_SURF) {
1009                 if(okee("Join selected NURBS")==0) return;
1010                 join_curve(OB_SURF);
1011         } else if(ob->type == OB_ARMATURE) {
1012                 /*      Make sure the user wants to continue*/
1013                 if(okee("Join selected armatures")==0) return;
1014                 join_armature ();
1015         } else {
1016                 error("This object type doesn't support joining");
1017         }
1018 }
1019
1020 static unsigned short convert_for_nonumpad(unsigned short event)
1021 {
1022         if (event>=ZEROKEY && event<=NINEKEY) {
1023                 return event - ZEROKEY + PAD0;
1024         } else if (event==MINUSKEY) {
1025                 return PADMINUS;
1026         } else if (event==EQUALKEY) {
1027                 return PADPLUSKEY;
1028         } else if (event==BACKSLASHKEY) {
1029                 return PADSLASHKEY;
1030         } else {
1031                 return event;
1032         }
1033 }
1034
1035 /* *************** */
1036
1037 void BIF_undo_push(char *str)
1038 {
1039         if(G.obedit) {
1040                 if (U.undosteps == 0) return;
1041
1042                 if(G.obedit->type==OB_MESH)
1043                         undo_push_mesh(str);
1044                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1045                         undo_push_curve(str);
1046                 else if (G.obedit->type==OB_FONT)
1047                         undo_push_font(str);
1048                 else if (G.obedit->type==OB_MBALL)
1049                         undo_push_mball(str);
1050                 else if (G.obedit->type==OB_LATTICE)
1051                         undo_push_lattice(str);
1052                 else if (G.obedit->type==OB_ARMATURE)
1053                         undo_push_armature(str);
1054         }
1055         else if(G.f & G_PARTICLEEDIT) {
1056                 if (U.undosteps == 0) return;
1057
1058                 PE_undo_push(str);
1059         }
1060         else {
1061                 if(U.uiflag & USER_GLOBALUNDO) 
1062                         BKE_write_undo(str);
1063         }
1064 }
1065
1066 void BIF_undo(void)
1067 {       
1068         if(G.obedit) {
1069                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1070                         undo_editmode_step(1);
1071         }
1072         else {
1073                 if(G.f & G_TEXTUREPAINT)
1074                         undo_imagepaint_step(1);
1075                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1076                         undo_imagepaint_step(1);
1077                 else if(G.f & G_PARTICLEEDIT)
1078                         PE_undo();
1079                 else {
1080                         /* now also in faceselect mode */
1081                         if(U.uiflag & USER_GLOBALUNDO) {
1082                                 BPY_scripts_clear_pyobjects();
1083                                 BKE_undo_step(1);
1084                                 sound_initialize_sounds();
1085                         }
1086                 }
1087         }
1088 }
1089
1090 void BIF_redo(void)
1091 {
1092         if(G.obedit) {
1093                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1094                         undo_editmode_step(-1);
1095         }
1096         else {
1097                 if(G.f & G_TEXTUREPAINT)
1098                         undo_imagepaint_step(-1);
1099                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1100                         undo_imagepaint_step(-1);
1101                 else if(G.f & G_PARTICLEEDIT)
1102                         PE_redo();
1103                 else {
1104                         /* includes faceselect now */
1105                         if(U.uiflag & USER_GLOBALUNDO) {
1106                                 BKE_undo_step(-1);
1107                                 sound_initialize_sounds();
1108                         }
1109                 }
1110         }
1111 }
1112
1113 void BIF_undo_menu(void)
1114 {
1115         if(G.obedit) {
1116                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1117                         undo_editmode_menu();
1118                 allqueue(REDRAWALL, 0);
1119         }
1120         else {
1121                 if(G.f & G_PARTICLEEDIT)
1122                         PE_undo_menu();
1123                 else if(U.uiflag & USER_GLOBALUNDO) {
1124                         char *menu= BKE_undo_menu_string();
1125                         if(menu) {
1126                                 short event= pupmenu_col(menu, 20);
1127                                 MEM_freeN(menu);
1128                                 if(event>0) {
1129                                         BKE_undo_number(event);
1130                                         sound_initialize_sounds();
1131                                 }
1132                         }
1133                 }
1134         }
1135 }
1136
1137 /* *************** */
1138
1139 void handle_view_middlemouse() {
1140         /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1141         if(U.flag & USER_VIEWMOVE) {
1142                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1143                         viewmove(0);
1144                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1145                         viewmove(2);
1146                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1147                         viewmove(1);
1148         }
1149         else {
1150                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1151                         viewmove(1);
1152                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1153                         viewmove(2);
1154                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1155                         viewmove(0);
1156         }
1157 }
1158
1159 void handle_view_wheelup()
1160 {
1161         /* Regular:   Zoom in */
1162         /* Shift:     Scroll up */
1163         /* Ctrl:      Scroll right */
1164         /* Alt-Shift: Rotate up */
1165         /* Alt-Ctrl:  Rotate right */
1166
1167         if( G.qual & LR_SHIFTKEY ) {
1168                 if( G.qual & LR_ALTKEY ) { 
1169                         G.qual &= ~LR_SHIFTKEY;
1170                         persptoetsen(PAD2);
1171                         G.qual |= LR_SHIFTKEY;
1172                 } else {
1173                         persptoetsen(PAD2);
1174                 }
1175         } else if( G.qual & LR_CTRLKEY ) {
1176                 if( G.qual & LR_ALTKEY ) { 
1177                         G.qual &= ~LR_CTRLKEY;
1178                         persptoetsen(PAD4);
1179                         G.qual |= LR_CTRLKEY;
1180                 } else {
1181                         persptoetsen(PAD4);
1182                 }
1183         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1184                 persptoetsen(PADMINUS);
1185         else
1186                 persptoetsen(PADPLUSKEY);
1187 }
1188
1189 void handle_view_wheeldown()
1190 {
1191         /* Regular:   Zoom out */
1192         /* Shift:     Scroll down */
1193         /* Ctrl:      Scroll left */
1194         /* Alt-Shift: Rotate down */
1195         /* Alt-Ctrl:  Rotate left */
1196
1197         if( G.qual & LR_SHIFTKEY ) {
1198                 if( G.qual & LR_ALTKEY ) { 
1199                         G.qual &= ~LR_SHIFTKEY;
1200                         persptoetsen(PAD8);
1201                         G.qual |= LR_SHIFTKEY;
1202                 } else {
1203                         persptoetsen(PAD8);
1204                 }
1205         } else if( G.qual & LR_CTRLKEY ) {
1206                 if( G.qual & LR_ALTKEY ) { 
1207                         G.qual &= ~LR_CTRLKEY;
1208                         persptoetsen(PAD6);
1209                         G.qual |= LR_CTRLKEY;
1210                 } else {
1211                         persptoetsen(PAD6);
1212                 }
1213         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1214                 persptoetsen(PADPLUSKEY);
1215         else
1216                 persptoetsen(PADMINUS);
1217 }
1218
1219 int mouse_in_header(ScrArea *sa)
1220 {
1221         short mouse[2];
1222         getmouseco_sc(mouse);
1223         return mouse[0] >= sa->headrct.xmin &&
1224                mouse[0] <= sa->headrct.xmax &&
1225                mouse[1] >= sa->headrct.ymin &&
1226                mouse[1] <= sa->headrct.ymax;
1227 }
1228
1229 static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
1230 {
1231         View3D *v3d= sa->spacedata.first;
1232         Object *ob= OBACT;      /* do not change! */
1233         float *curs;
1234         int doredraw= 0, pupval;
1235         unsigned short event= evt->event;
1236         short val= evt->val;
1237         char ascii= evt->ascii;
1238         
1239         if(curarea->win==0) return;     /* when it comes from sa->headqread() */
1240         
1241         if(val) {
1242
1243                 if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
1244                 
1245                 if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
1246                 
1247                 /* - we consider manipulator a button, defaulting to leftmouse 
1248                  * - grease-pencil also defaults to leftmouse
1249                  */
1250                 if(event==LEFTMOUSE) {
1251                         /* run any view3d event handler script links */
1252                         if (sa->scriptlink.totscript) {
1253                                 if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1254                                         return; /* return if event was processed (swallowed) by handler(s) */
1255                         }
1256                         
1257                         if(gpencil_do_paint(sa, L_MOUSE)) return;
1258                         if(BIF_do_manipulator(sa)) return;
1259                 }
1260                 else if(event==RIGHTMOUSE) {
1261                         if(gpencil_do_paint(sa, R_MOUSE)) return;
1262                 }
1263                 
1264                 /* swap mouse buttons based on user preference */
1265                 if (U.flag & USER_LMOUSESELECT) {
1266                         /* only swap mouse button for selection, in modes where it is relevant.
1267                          * painting/sculpting stays on LEFTMOUSE */
1268                         if (   !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) || (G.f & G_GREASEPENCIL) ||
1269                                 (G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_PARTICLEEDIT)) ||
1270                                 (G.obedit) )
1271                         {                       
1272                                 if (event==LEFTMOUSE) event = RIGHTMOUSE;
1273                                 else if (event==RIGHTMOUSE) event = LEFTMOUSE;
1274                         }
1275                 }
1276
1277                 if(!mouse_in_header(sa)) {
1278                         if(!G.obedit && (G.f & G_SCULPTMODE)) {
1279                                 SculptSession *ss= sculpt_session();
1280                                 if(ss && ss->radialcontrol) {
1281                                         radialcontrol_do_events(ss->radialcontrol, event);
1282                                         return;
1283                                 }
1284                                 else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
1285                                         if(!bwin_qtest(sa->win))
1286                                                 allqueue(REDRAWVIEW3D, 0);
1287                                 }
1288                         }
1289                         else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
1290                                 ParticleSystem *psys=PE_get_current(OBACT);
1291                                 ParticleEditSettings *pset=PE_settings();
1292                                 if(*PE_radialcontrol()) {
1293                                         radialcontrol_do_events(*PE_radialcontrol(), event);
1294                                         return;
1295                                 }
1296                                 if(psys && psys->edit){
1297                                         if(pset->brushtype>=0 &&
1298                                                 event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
1299                                                 (event==MOUSEY || event==MOUSEX) && bwin_qtest(sa->win)==0) {
1300                                                 allqueue(REDRAWVIEW3D, 0);
1301                                         }
1302                                 }
1303                         }
1304
1305                         /* Handle retopo painting */
1306                         if(retopo_mesh_paint_check()) {
1307                                 if(!retopo_paint(event))
1308                                         return;
1309                         }
1310                 }
1311
1312                 /* run any view3d event handler script links */
1313                 if (event && sa->scriptlink.totscript)
1314                         if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1315                                 return; /* return if event was processed (swallowed) by handler(s) */
1316
1317                 /* TEXTEDITING?? */
1318                 if((G.obedit) && G.obedit->type==OB_FONT) {
1319                         switch(event) {
1320                         
1321                         case LEFTMOUSE:
1322                                 mouse_cursor();
1323                                 break;
1324                         case MIDDLEMOUSE:
1325                                 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1326                                 if(U.flag & USER_VIEWMOVE) {
1327                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1328                                                 viewmove(0);
1329                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1330                                                 viewmove(2);
1331                                         else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1332                                                 viewmove(1);
1333                                 }
1334                                 else {
1335                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1336                                                 viewmove(1);
1337                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1338                                                 viewmove(2);
1339                                         else
1340                                                 viewmove(0);
1341                                 }
1342                                 break;
1343                                 
1344                         case WHEELUPMOUSE:
1345                                 /* Regular:   Zoom in */
1346                                 /* Shift:     Scroll up */
1347                                 /* Ctrl:      Scroll right */
1348                                 /* Alt-Shift: Rotate up */
1349                                 /* Alt-Ctrl:  Rotate right */
1350
1351                                 if( G.qual & LR_SHIFTKEY ) {
1352                                         if( G.qual & LR_ALTKEY ) { 
1353                                                 G.qual &= ~LR_SHIFTKEY;
1354                                                 persptoetsen(PAD2);
1355                                                 G.qual |= LR_SHIFTKEY;
1356                                         } else {
1357                                                 persptoetsen(PAD2);
1358                                         }
1359                                 } else if( G.qual & LR_CTRLKEY ) {
1360                                         if( G.qual & LR_ALTKEY ) { 
1361                                                 G.qual &= ~LR_CTRLKEY;
1362                                                 persptoetsen(PAD4);
1363                                                 G.qual |= LR_CTRLKEY;
1364                                         } else {
1365                                                 persptoetsen(PAD4);
1366                                         }
1367                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1368                                         persptoetsen(PADMINUS);
1369                                 else
1370                                         persptoetsen(PADPLUSKEY);
1371
1372                                 doredraw= 1;
1373                                 break;
1374
1375                         case WHEELDOWNMOUSE:
1376                                 /* Regular:   Zoom out */
1377                                 /* Shift:     Scroll down */
1378                                 /* Ctrl:      Scroll left */
1379                                 /* Alt-Shift: Rotate down */
1380                                 /* Alt-Ctrl:  Rotate left */
1381
1382                                 if( G.qual & LR_SHIFTKEY ) {
1383                                         if( G.qual & LR_ALTKEY ) { 
1384                                                 G.qual &= ~LR_SHIFTKEY;
1385                                                 persptoetsen(PAD8);
1386                                                 G.qual |= LR_SHIFTKEY;
1387                                         } else {
1388                                                 persptoetsen(PAD8);
1389                                         }
1390                                 } else if( G.qual & LR_CTRLKEY ) {
1391                                         if( G.qual & LR_ALTKEY ) { 
1392                                                 G.qual &= ~LR_CTRLKEY;
1393                                                 persptoetsen(PAD6);
1394                                                 G.qual |= LR_CTRLKEY;
1395                                         } else {
1396                                                 persptoetsen(PAD6);
1397                                         }
1398                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1399                                         persptoetsen(PADPLUSKEY);
1400                                 else
1401                                         persptoetsen(PADMINUS);
1402                                 
1403                                 doredraw= 1;
1404                                 break;
1405
1406                         case UKEY:
1407                                 if(G.qual==LR_ALTKEY) {
1408                                         remake_editText();
1409                                         doredraw= 1;
1410                                 } 
1411                                 else {
1412                                         do_textedit(event, val, ascii);
1413                                 }
1414                                 break;
1415                         case VKEY:
1416                                 if(G.qual==LR_ALTKEY) {
1417                                         paste_editText();
1418                                         doredraw= 1;
1419                                 } 
1420                                 else {
1421                                         do_textedit(event, val, ascii);
1422                                 }
1423                                 break;
1424                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1425                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1426                         case PADENTER:
1427                                 persptoetsen(event);
1428                                 doredraw= 1;
1429                                 break;
1430                                 
1431                         default:
1432                                 do_textedit(event, val, ascii);
1433                                 break;
1434                         }
1435                 }
1436                 else if(!G.obedit && (G.f & G_SCULPTMODE)) {
1437                         SculptData *sd= sculpt_data();
1438                         SculptSession *ss= sculpt_session();
1439                         BrushData *br= sculptmode_brush();
1440                         Mesh *me= get_mesh(OBACT);
1441                         char update_prop= 0;
1442                         
1443                         if(U.flag & USER_NONUMPAD) {
1444                                 event= convert_for_nonumpad(event);
1445                         }
1446                         
1447                         switch(event) {
1448                         case LEFTMOUSE:
1449                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1450                                         sculptmode_pmv(0);
1451                                 else if(!(ss && ss->radialcontrol))
1452                                         sculpt();
1453                                 break;
1454                         /* View */
1455                         case MIDDLEMOUSE:
1456                                 handle_view_middlemouse();
1457                                 break;
1458                         case WHEELUPMOUSE:
1459                                 handle_view_wheelup();
1460                                 doredraw= 1;
1461                                 break;
1462                         case WHEELDOWNMOUSE:
1463                                 handle_view_wheeldown();
1464                                 doredraw= 1;
1465                                 break;
1466                         case RIGHTMOUSE:
1467                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1468                                         sculptmode_pmv(1);
1469                                 break;
1470                         case CKEY:
1471                                 if(G.qual==LR_SHIFTKEY) {
1472                                         view3d_home(1);
1473                                         curs= give_cursor();
1474                                         curs[0]=curs[1]=curs[2]= 0.0;
1475                                         allqueue(REDRAWVIEW3D, 0);
1476                                 }
1477                                 else if(G.qual==0) {
1478                                         if (G.vd->persp==V3D_CAMOB)
1479                                                 /* center the camera offset */
1480                                                 G.vd->camdx= G.vd->camdy= 0.0;
1481                                         else {
1482                                                 /*non camera center*/
1483                                                 float new_ofs[3];
1484                                                 curs= give_cursor();
1485                                                 new_ofs[0]= -curs[0];
1486                                                 new_ofs[1]= -curs[1];
1487                                                 new_ofs[2]= -curs[2];
1488                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1489                                         }
1490                                 }
1491                                 doredraw= 1;
1492                                 break;
1493                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1494                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1495                         case PADPLUSKEY:
1496                         case PADMINUS:
1497                         case PADENTER:
1498                                 persptoetsen(event);
1499                                 doredraw= 1;
1500                                 break;
1501                         case BKEY:
1502                                 if(G.qual==LR_ALTKEY)
1503                                         view3d_edit_clipping(v3d);
1504                                 else if(G.qual==LR_SHIFTKEY) {
1505                                         if(G.vd->persp==V3D_CAMOB)
1506                                                 set_render_border();
1507                                         else
1508                                                 view3d_border_zoom();
1509                                 }
1510                                 break;
1511                         case PADSLASHKEY:
1512                                 if(!G.qual) {
1513                                         if(G.vd->localview) {
1514                                                 G.vd->localview= 0;
1515                                                 endlocalview(curarea);
1516                                         }
1517                                         else {
1518                                                 G.vd->localview= 1;
1519                                                 initlocalview();
1520                                         }
1521                                         allqueue(REDRAWVIEW3D, 1);
1522                                 }
1523                                 break;
1524                         /* Brush properties */
1525                         case AKEY:
1526                                 if(G.qual==LR_SHIFTKEY)
1527                                         br->flag ^= SCULPT_BRUSH_ANCHORED;
1528                                 else
1529                                         br->flag ^= SCULPT_BRUSH_AIRBRUSH;
1530                                 update_prop= 1; break;
1531                         case FKEY:
1532                                 if(ss) {
1533                                         sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
1534                                                                    G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
1535                                                                    G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
1536                                                                    RADIALCONTROL_NONE);
1537                                 }
1538                                 break;
1539                         case VKEY:
1540                                 br->dir= br->dir==1 ? 2 : 1;
1541                                 update_prop= 1; break;
1542                         /* Set brush */
1543                         case DKEY:
1544                                 sd->brush_type= DRAW_BRUSH;
1545                                 update_prop= 1; break;
1546                         case SKEY:
1547                                 if(G.qual==LR_SHIFTKEY)
1548                                         sd->flags ^= SCULPT_INPUT_SMOOTH;
1549                                 else {
1550                                         sd->brush_type= SMOOTH_BRUSH;
1551                                         update_prop= 1;
1552                                 }
1553                                 break;
1554                         case PKEY:
1555                                 sd->brush_type= PINCH_BRUSH;
1556                                 update_prop= 1; break;
1557                         case IKEY:
1558                                 sd->brush_type= INFLATE_BRUSH;
1559                                 update_prop= 1; break;
1560                         case GKEY:
1561                                 sd->brush_type= GRAB_BRUSH;
1562                                 update_prop= 1; break;
1563                         case LKEY:
1564                                 sd->brush_type= LAYER_BRUSH;
1565                                 update_prop= 1; break;
1566                         case TKEY:
1567                                 sd->brush_type= FLATTEN_BRUSH;
1568                                 update_prop= 1; break;
1569                         /* Symmetry */
1570                         case XKEY:
1571                                 sd->symm^= SYMM_X;
1572                                 update_prop= 1; break;
1573                         case YKEY:
1574                                 sd->symm^= SYMM_Y;
1575                                 update_prop= 1; break;
1576                         case ZKEY:
1577                                 sd->symm^= SYMM_Z;
1578                                 update_prop= 1; break;
1579                         /* Interface */
1580                         case NKEY:
1581                                 if(G.qual==0) {
1582                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1583                                         allqueue(REDRAWVIEW3D, 0);
1584                                 }
1585                                 break;
1586                         /* Multires */
1587                         case PAGEUPKEY:
1588                                 if(me && me->mr) {
1589                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
1590                                         multires_set_level_cb(ob, ob->data);
1591                                 }
1592                                 break;
1593                         case PAGEDOWNKEY:
1594                                 if(me && me->mr) {
1595                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
1596                                         multires_set_level_cb(ob, ob->data);
1597                                 }
1598                                 break;
1599                         /* Partial Visibility */
1600                         case HKEY:
1601                                 if(G.qual==LR_ALTKEY) {
1602                                         waitcursor(1);
1603                                         mesh_pmv_off(ob, get_mesh(ob));
1604                                         BIF_undo_push("Partial mesh hide");
1605                                         allqueue(REDRAWVIEW3D,0);
1606                                         waitcursor(0);
1607                                 }
1608                                 break;
1609                         /* Layers */
1610                         case ONEKEY:
1611                                 do_layer_buttons(0); break;
1612                         case TWOKEY:
1613                                 do_layer_buttons(1); break;
1614                         case THREEKEY:
1615                                 do_layer_buttons(2); break;
1616                         case FOURKEY:
1617                                 do_layer_buttons(3); break;
1618                         case FIVEKEY:
1619                                 do_layer_buttons(4); break;
1620                         case SIXKEY:
1621                                 do_layer_buttons(5); break;
1622                         case SEVENKEY:
1623                                 do_layer_buttons(6); break;
1624                         case EIGHTKEY:
1625                                 do_layer_buttons(7); break;
1626                         case NINEKEY:
1627                                 do_layer_buttons(8); break;
1628                         case ZEROKEY:
1629                                 do_layer_buttons(9); break;
1630                         case MINUSKEY:
1631                                 do_layer_buttons(10); break;
1632                         case EQUALKEY:
1633                                 do_layer_buttons(11); break;
1634                         case ACCENTGRAVEKEY:
1635                                 do_layer_buttons(-1); break;
1636                         
1637                         case NDOFMOTION:                
1638                                 if (G.vd->ndofmode == 0) {
1639                                         viewmoveNDOF(1);
1640                                 } else if (G.vd->ndofmode == 1) {
1641                                         viewmoveNDOFfly(1);
1642                                 } else {
1643                                         NDofTransform();
1644                                 }
1645                 break;
1646                                 
1647             case NDOFBUTTON:
1648                                 if (val == 1) {
1649                                         G.vd->ndofmode +=1;
1650                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1651                                                 G.vd->ndofmode = 0;
1652                                 }
1653                                 if (val == 2) {
1654                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1655                                 }
1656                                 allqueue(REDRAWHEADERS, 0);
1657                 break;
1658                                 
1659                         }
1660                         
1661                         /* Redraw buttons window as well as view 3d (for floating panel) */
1662                         if(update_prop) {
1663                                 allqueue(REDRAWVIEW3D, 0);
1664                                 allqueue(REDRAWBUTSEDIT, 0);
1665                         }
1666                 } else {
1667
1668                         if (U.flag & USER_NONUMPAD) {
1669                                 event= convert_for_nonumpad(event);
1670                         }
1671
1672                         switch(event) {
1673                         
1674                         /* Afterqueue events */
1675                         case BACKBUFDRAW:
1676                                 backdrawview3d(1);
1677                                 break;
1678                         case RENDERPREVIEW:
1679                                 BIF_view3d_previewrender(sa);
1680                                 break;
1681                                 
1682                         case TABKEY:
1683                                 /* Shift-Tabe handling (other cases are in toets) */
1684                                 if (G.qual == LR_SHIFTKEY)
1685                                 {
1686                                         /* Snap toggle only when supported */
1687                                         if (BIF_snappingSupported())
1688                                         {
1689                                                 G.scene->snap_flag ^= SCE_SNAP;
1690                                                 allqueue(REDRAWHEADERS, 0);
1691                                         }                                       
1692                                 }
1693                                 break;
1694                                 
1695                         /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
1696                          * based on user preference USER_LMOUSESELECT
1697                          */
1698                         case LEFTMOUSE: 
1699                                 if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_PARTICLEEDIT))) {
1700                                         mouse_cursor();
1701                                 }
1702                                 else if (G.f & G_WEIGHTPAINT) {
1703                                         weight_paint();
1704                                 }
1705                                 else if (G.f & G_VERTEXPAINT) {
1706                                         vertex_paint();
1707                                 }
1708                                 else if (G.f & G_TEXTUREPAINT) {
1709                                         imagepaint_paint(L_MOUSE, 1);
1710                                 }
1711                                 else if (G.f & G_PARTICLEEDIT) {
1712                                         if(G.qual & LR_CTRLKEY)
1713                                                 mouse_cursor();
1714                                         else if(!PE_brush_particles())
1715                                                 mouse_cursor();
1716                                 }
1717                                 break;
1718                         case MIDDLEMOUSE:
1719                                 handle_view_middlemouse();
1720                                 break;
1721                         case RIGHTMOUSE:
1722                                 if((G.obedit) && (G.qual & LR_CTRLKEY)==0) {
1723                                         if(G.obedit->type==OB_MESH)
1724                                                 mouse_mesh();
1725                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1726                                                 mouse_nurb();
1727                                         else if(G.obedit->type==OB_MBALL)
1728                                                 mouse_mball();
1729                                         else if(G.obedit->type==OB_LATTICE)
1730                                                 mouse_lattice();
1731                                         else if(G.obedit->type==OB_ARMATURE)
1732                                                 mouse_armature();
1733                                 }
1734                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
1735                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1736                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
1737                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1738                                 else if(G.qual==LR_CTRLKEY)
1739                                         mouse_select(); /* also allow in editmode, for vertex parenting */
1740                                 else if(FACESEL_PAINT_TEST)
1741                                         face_select();
1742                                 else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
1743                                         sample_vpaint();
1744                                 else if( G.f & G_PARTICLEEDIT)
1745                                         PE_mouse_particles();
1746                                 else
1747                                         mouse_select(); /* does poses too */
1748                                 break;
1749                         case WHEELUPMOUSE:
1750                                 handle_view_wheelup();
1751                                 doredraw= 1;
1752                                 break;
1753                         case WHEELDOWNMOUSE:
1754                                 handle_view_wheeldown();
1755                                 doredraw= 1;
1756                                 break;
1757
1758             case NDOFMOTION:            
1759                                 if (G.vd->ndofmode == 0) {
1760                                         viewmoveNDOF(1);
1761                                 } else if (G.vd->ndofmode == 1) {
1762                                         viewmoveNDOFfly(1);
1763                                 } else {
1764                                         NDofTransform();
1765                                 }
1766                 break;
1767
1768             case NDOFBUTTON:
1769                                 if (val == 1) {
1770                                         G.vd->ndofmode +=1;
1771                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1772                                                 G.vd->ndofmode = 0;
1773                                 }
1774                                 if (val == 2) {
1775                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1776                                 }
1777                                 allqueue(REDRAWHEADERS, 0);
1778                 break;
1779                                 
1780                         case ONEKEY:
1781                                 if(G.qual==LR_CTRLKEY) {
1782                                         flip_subdivison(1);
1783                                 }
1784                                 else do_layer_buttons(0); 
1785                                 break;
1786                                 
1787                         case TWOKEY:
1788                                 if(G.qual==LR_CTRLKEY) {
1789                                         flip_subdivison(2);
1790                                 }
1791                                 else do_layer_buttons(1); 
1792                                 break;
1793                                 
1794                         case THREEKEY:
1795                                 if(G.qual==LR_CTRLKEY) {
1796                                         flip_subdivison(3);
1797                                 }
1798                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1799                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1800                                                 select_faces_by_numverts(3);
1801                                 }
1802                                 else do_layer_buttons(2); 
1803                                 break;
1804                                 
1805                         case FOURKEY:
1806                                 if(G.qual==LR_CTRLKEY) {
1807                                         flip_subdivison(4);
1808                                 }
1809                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1810                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1811                                                 select_faces_by_numverts(4);
1812                                 }
1813                                 else do_layer_buttons(3); 
1814                                 break;
1815                                 
1816                         case FIVEKEY:
1817                                 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1818                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1819                                                 select_faces_by_numverts(5);
1820                                 }
1821                                 
1822                                 else if(G.qual==LR_CTRLKEY) {}
1823                                 else do_layer_buttons(4);
1824                                 break;
1825
1826                         case SIXKEY:
1827                                 if(G.qual==LR_CTRLKEY) {}
1828                                 else do_layer_buttons(5);
1829                                 break;
1830                         case SEVENKEY:
1831                                 if(G.qual==LR_CTRLKEY) {}
1832                                 else do_layer_buttons(6);
1833                                 break;
1834                         case EIGHTKEY:
1835                                 if(G.qual==LR_CTRLKEY) {}
1836                                 else do_layer_buttons(7);
1837                                 break;
1838                         case NINEKEY:
1839                                 if(G.qual==LR_CTRLKEY) {}
1840                                 else do_layer_buttons(8);
1841                                 break;
1842                         case ZEROKEY:
1843                                 if(G.qual==LR_CTRLKEY) {}
1844                                 else do_layer_buttons(9);
1845                                 break;
1846                         case MINUSKEY:
1847                                 if(G.qual==LR_CTRLKEY) {}
1848                                 else do_layer_buttons(10);
1849                                 break;
1850                         case EQUALKEY:
1851                                 if(G.qual==LR_CTRLKEY) {}
1852                                 else do_layer_buttons(11);
1853                                 break;
1854                         case ACCENTGRAVEKEY:
1855                                 do_layer_buttons(-1);
1856                                 break;
1857                         
1858                         case SPACEKEY:
1859                                 if(G.qual == LR_CTRLKEY) {
1860                                         val= pupmenu("Manipulator%t|Enable/Disable|Translate|Rotate|Scale|Combo");
1861                                         if(val>0) {
1862                                                 if(val==1) v3d->twflag ^= V3D_USE_MANIPULATOR;
1863                                                 else {
1864                                                         if(val==2) v3d->twtype= V3D_MANIP_TRANSLATE;
1865                                                         else if(val==3) v3d->twtype= V3D_MANIP_ROTATE;
1866                                                         else if(val==4) v3d->twtype= V3D_MANIP_SCALE;
1867                                                         else if(val==5) v3d->twtype= V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE|V3D_MANIP_SCALE;
1868                                                         v3d->twflag |= V3D_USE_MANIPULATOR;
1869                                                 }
1870                                                 doredraw= 1;
1871                                         }
1872                                 }
1873                                 else if(G.qual == LR_ALTKEY) {
1874                                         BIF_selectOrientation();
1875                                         doredraw= 1;
1876                                 }
1877
1878                                 break;
1879                                 
1880                         case AKEY:
1881                                 if(G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
1882                                         if(G.obedit == 0)
1883                                                 alignmenu();
1884                                         else if(G.obedit->type==OB_ARMATURE)
1885                                                 align_selected_bones();
1886                                 }
1887                                 else if(G.qual & LR_CTRLKEY) { /* also with shift! */
1888                                         apply_object(); 
1889                                 }
1890                                 else if((G.qual==LR_SHIFTKEY)) {
1891                                         toolbox_n_add();
1892                                 }
1893                                 else {
1894                                         if(G.obedit) {
1895                                                 if(G.obedit->type==OB_MESH)
1896                                                         deselectall_mesh();
1897                                                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1898                                                         deselectall_nurb();
1899                                                 else if(G.obedit->type==OB_MBALL)
1900                                                         deselectall_mball();
1901                                                 else if(G.obedit->type==OB_LATTICE)
1902                                                         deselectall_Latt();
1903                                                 else if(G.obedit->type==OB_ARMATURE)
1904                                                         deselectall_armature(1, 1);     /* 1 == toggle */
1905                                         }
1906                                         else if (ob && (ob->flag & OB_POSEMODE)){
1907                                                 deselectall_posearmature(ob, 1, 1);
1908                                         }
1909                                         else {
1910                                                 if(FACESEL_PAINT_TEST) deselectall_tface();
1911                                                 else if(G.f & G_PARTICLEEDIT) PE_deselectall();
1912                                                 else {
1913                                                         /* by design, the center of the active object 
1914                                                          * (which need not necessarily by selected) will
1915                                                          * still be drawn as if it were selected.
1916                                                          */
1917                                                         deselectall();
1918                                                 }
1919                                         }
1920                                 }
1921                                 break;
1922                         case BKEY:
1923                                 if(G.qual==LR_ALTKEY)
1924                                         view3d_edit_clipping(v3d);
1925                                 else if(G.qual==LR_SHIFTKEY)
1926                                 {
1927                                         if(G.vd->persp==V3D_CAMOB)
1928                                                 set_render_border();
1929                                         else
1930                                                 view3d_border_zoom();
1931                                 }
1932                                 else if(G.qual==LR_CTRLKEY) {
1933                                         extern void pointcache_bake(PTCacheID *pid, int startframe);
1934                                         extern void pointcache_free(PTCacheID *pid, int cacheonly);
1935                                         extern void fluidsimBake(Object *ob);
1936                                         extern void fluidsimFreeBake(Object *ob);
1937                                         int pupval;
1938
1939                                         pupval= pupmenu("Physics Baking%t|Bake selected %x1|Free bake selected %x2|Free cache selected %x3");
1940
1941                                         if(pupval > 0) {
1942                                                 if(pupval == 1) {
1943                                                         pointcache_bake(NULL, 0);
1944                                                         /* also bake first domain of selected objects... */
1945                                                         fluidsimBake(NULL);
1946                                                 }
1947                                                 else if(pupval == 2) {
1948                                                         pointcache_free(NULL, 0);
1949                                                         fluidsimFreeBake(NULL);
1950                                                 }
1951                                                 else if(pupval == 3)
1952                                                         pointcache_free(NULL, 1);
1953                                         }
1954                                 }
1955                                 else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
1956                                         objects_bake_render_menu();
1957                                 else if(G.qual==0)
1958                                         borderselect();
1959                                 break;
1960                         case CKEY:
1961                                 if(G.qual==LR_CTRLKEY) {
1962                                         if(ob && (ob->flag & OB_POSEMODE))
1963                                                 pose_copy_menu();       /* poseobject.c */
1964                                         else
1965                                                 copy_attr_menu();
1966                                 }
1967                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) 
1968                                         gpencil_convert_menu(); /* gpencil.c */
1969                                 else if(G.qual==LR_ALTKEY) {
1970                                         if(ob && (ob->flag & OB_POSEMODE))
1971                                                 pose_clear_constraints();       /* poseobject.c */
1972                                         else
1973                                                 convertmenu();  /* editobject.c */
1974                                 }
1975                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) 
1976                                         add_constraint(0);      /* editconstraint.c, generic for objects and posemode */
1977                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) {
1978                                         BIF_manageTransformOrientation(0, 1);
1979                                         allqueue(REDRAWVIEW3D, 0);
1980                                 }
1981                                 else if((G.qual==LR_SHIFTKEY)) {
1982                                         view3d_home(1);
1983                                         curs= give_cursor();
1984                                         curs[0]=curs[1]=curs[2]= 0.0;
1985                                         allqueue(REDRAWVIEW3D, 0);
1986                                 }
1987                                 else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) {
1988                                         makecyclicNurb();
1989                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1990                                         allqueue(REDRAWVIEW3D, 0);
1991                                 }
1992                                 else if((G.qual==0)){
1993                                         if (G.vd->persp==V3D_CAMOB)
1994                                                 /* center the camera offset */
1995                                                 G.vd->camdx= G.vd->camdy= 0.0;
1996                                         else {
1997                                                 /*non camera center*/
1998                                                 float new_ofs[3];
1999                                                 curs= give_cursor();
2000                                                 new_ofs[0]= -curs[0];
2001                                                 new_ofs[1]= -curs[1];
2002                                                 new_ofs[2]= -curs[2];
2003                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
2004                                         }
2005                                         scrarea_queue_winredraw(curarea);
2006                                 }
2007                                 break;
2008                         case DKEY:
2009                                 if((G.qual==LR_SHIFTKEY)) {
2010                                         duplicate_context_selected();
2011                                 }
2012                                 else if(G.qual==LR_ALTKEY) {
2013                                         if(ob && (ob->flag & OB_POSEMODE))
2014                                                 error ("Duplicate not possible in posemode.");
2015                                         else if((G.obedit==NULL))
2016                                                 adduplicate(0, 0);
2017                                 }
2018                                 else if(G.qual==LR_CTRLKEY) {
2019                                         imagestodisplist(); // removed
2020                                 }
2021                                 else if((G.qual==0)){
2022                                         pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
2023                                         if(pupval>0) {
2024                                                 G.vd->drawtype= pupval;
2025                                                 doredraw= 1;
2026                                         }
2027                 }
2028                                 
2029                                 break;
2030                         case EKEY:
2031                                 if (G.qual==0){
2032                                         if(G.obedit) {
2033                                                 if(G.obedit->type==OB_MESH)
2034                                                         extrude_mesh();
2035                                                 else if(G.obedit->type==OB_CURVE)
2036                                                         addvert_Nurb('e');
2037                                                 else if(G.obedit->type==OB_SURF)
2038                                                         extrude_nurb();
2039                                                 else if(G.obedit->type==OB_ARMATURE)
2040                                                         extrude_armature(0);
2041                                         }
2042                                 }
2043                                 else if (G.qual==LR_CTRLKEY) {
2044                                         if(G.obedit && G.obedit->type==OB_MESH)
2045                                                 Edge_Menu();
2046                                         else if (FACESEL_PAINT_TEST)
2047                                                 seam_mark_clear_tface(0);
2048                                 }
2049                                 else if (G.qual==LR_SHIFTKEY) {
2050                                         if (G.obedit && G.obedit->type==OB_MESH &&
2051                                             !multires_level1_test()) {
2052                                                 initTransform(TFM_CREASE, CTX_EDGE);
2053                                                 Transform();
2054                                         }
2055                                         else if (G.obedit && G.obedit->type==OB_ARMATURE) {
2056                                                 extrude_armature(1);
2057                                         }
2058                                 }
2059                                 else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
2060                                         if (G.obedit && G.obedit->type==OB_MESH &&
2061                                             !multires_level1_test()) {
2062                                                 if (G.scene->selectmode & SCE_SELECT_VERTEX) {
2063                                                         initTransform(TFM_BWEIGHT, CTX_NONE);
2064                                                 }
2065                                                 else {
2066                                                         initTransform(TFM_BWEIGHT, CTX_EDGE);
2067                                                 }
2068                                                 Transform();
2069                                         }
2070                                 }
2071                                 break;
2072                         case FKEY:
2073                                 if(G.obedit) {
2074                                         if(G.obedit->type==OB_MESH) {
2075                                                 if(G.qual == LR_CTRLKEY)
2076                                                         Face_Menu();
2077                                                 else if((G.qual==LR_SHIFTKEY))
2078                                                         fill_mesh();
2079                                                 else if(G.qual==LR_ALTKEY)
2080                                                         beauty_fill();
2081                                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY))
2082                                                         edge_flip();
2083                                                 else if (G.qual==0)
2084                                                         addedgeface_mesh();
2085                                                 else if ( G.qual == 
2086                                                          (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2087                                                         select_linked_flat_faces();
2088                                                 }
2089
2090                                         }
2091                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2092                                                 addsegment_nurb();
2093                                         }
2094                                         else if(G.obedit->type == OB_ARMATURE) {
2095                                                 fill_bones_armature();
2096                                         }
2097                                 }
2098                                 else if(G.qual==LR_CTRLKEY)
2099                                         sort_faces();
2100                                 else if((G.qual==LR_SHIFTKEY)) {
2101                                         if(ob && (ob->flag & OB_POSEMODE))
2102                                            pose_activate_flipped_bone();
2103                                         else if(G.f & G_WEIGHTPAINT)
2104                                                 pose_activate_flipped_bone();
2105                                         else if(G.f & G_PARTICLEEDIT)
2106                                                 PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
2107                                         else
2108                                                 fly();
2109                                 }
2110                                 else if((G.qual==LR_ALTKEY)) {
2111                                         if(ob && (ob->flag & OB_POSEMODE))
2112                                                 if(okee("Flip quaternion rotations"))
2113                                                         pose_flipquats();
2114                                 }
2115                                 else {
2116                                         if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)){
2117                                                 G.f ^= G_FACESELECT;
2118                                                 allqueue(REDRAWVIEW3D, 1);
2119                                                 allqueue(REDRAWBUTSEDIT, 1);
2120                                         }
2121                                         else if(G.f & G_PARTICLEEDIT) {
2122                                                 PE_radialcontrol_start(RADIALCONTROL_SIZE);
2123                                         } else {
2124                                                 pupmenu("Note%t|UV/Face Select was removed. Editmode now allows UV editing, Add a UV layer or Unwrap (UKey)");
2125                                         }
2126                                 }
2127                                 
2128                                 break;
2129                         case GKEY:
2130                                 if((G.qual == LR_CTRLKEY)) {
2131                                         if(G.obedit) {
2132                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2133                                                         vgroup_assign_with_menu();
2134                                         }
2135                                         else if(ob && (ob->flag & OB_POSEMODE))
2136                                                 pgroup_operation_with_menu();
2137                                         else
2138                                                 group_operation_with_menu();
2139                                 }
2140                                 else if((G.qual == (LR_CTRLKEY|LR_SHIFTKEY))) {
2141                                         if(G.obedit) {
2142                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2143                                                         vgroup_operation_with_menu();
2144                                         }
2145                                 }
2146                                 else if((G.qual==LR_SHIFTKEY)) {
2147                                         if(G.obedit) {
2148                                                 if(G.obedit->type==OB_MESH)
2149                                                         select_mesh_group_menu();
2150                                         } 
2151                                         else if(ob && (ob->flag & OB_POSEMODE))
2152                                                 pose_select_grouped_menu();
2153                                         else if (ob)
2154                                                 select_object_grouped_menu();
2155                                 }
2156                                 else if((G.obedit==0) && G.qual==LR_ALTKEY) {
2157                                         if(okee("Clear location")) {
2158                                                 clear_object('g');
2159                                         }
2160                                 }
2161                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2162                                         v3d->twtype= V3D_MANIP_TRANSLATE;
2163                                         doredraw= 1;
2164                                 }
2165                                 else if((G.qual==0)) {
2166                                         initTransform(TFM_TRANSLATION, CTX_NONE);
2167                                         Transform();
2168                                 }
2169                                 break;
2170                         case HKEY:
2171                                 if(G.obedit) {
2172                                         if(G.obedit->type==OB_MESH) {
2173                                                 if(G.qual==LR_CTRLKEY)
2174                                                         add_hook_menu();
2175                                                 else if(G.qual==LR_ALTKEY)
2176                                                         reveal_mesh();
2177                                                 else if((G.qual==LR_SHIFTKEY))
2178                                                         hide_mesh(1);
2179                                                 else if((G.qual==0)) 
2180                                                         hide_mesh(0);
2181                                         }
2182                                         else if(G.obedit->type== OB_SURF) {
2183                                                 if(G.qual==LR_CTRLKEY)
2184                                                         add_hook_menu();
2185                                                 else if(G.qual==LR_ALTKEY)
2186                                                         revealNurb();
2187                                                 else if((G.qual==LR_SHIFTKEY))
2188                                                         hideNurb(1);
2189                                                 else if((G.qual==0))
2190                                                         hideNurb(0);
2191                                         }
2192                                         else if(G.obedit->type==OB_CURVE) {
2193                                                 if(G.qual==LR_CTRLKEY)
2194                                                         add_hook_menu();
2195                                                 else if(G.qual==LR_ALTKEY)
2196                                                         revealNurb();
2197                                                 /* should be G.qual==LR_SHIFTKEY, but that is taken fro handles already */
2198                                                 else if((G.qual==(LR_ALTKEY|LR_SHIFTKEY))) 
2199                                                         hideNurb(1);
2200                                                 /* should be G.qual==0, but that is taken for handles already */
2201                                                 else if((G.qual==(LR_ALTKEY|LR_CTRLKEY))) 
2202                                                         hideNurb(0);
2203                                                 else {
2204                                                         if(G.qual==LR_CTRLKEY) /* conflict */
2205                                                                 autocalchandlesNurb_all(1);     /* flag=1, selected */
2206                                                         else if((G.qual==LR_SHIFTKEY))
2207                                                                 sethandlesNurb(1);
2208                                                         else if((G.qual==0))
2209                                                                 sethandlesNurb(3);
2210                                                         
2211                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2212                                                         BIF_undo_push("Handle change");
2213                                                         allqueue(REDRAWVIEW3D, 0);
2214                                                 }
2215                                         }
2216                                         else if(G.obedit->type==OB_LATTICE) {
2217                                                 if(G.qual==LR_CTRLKEY) add_hook_menu();
2218                                         }
2219                                         else if(G.obedit->type==OB_MBALL) {
2220                                                 if(G.qual==LR_ALTKEY)
2221                                                         reveal_mball();
2222                                                 else if((G.qual==LR_SHIFTKEY))
2223                                                         hide_mball(1);
2224                                                 else if((G.qual==0)) 
2225                                                         hide_mball(0);
2226                                         }
2227                                         else if(G.obedit->type==OB_ARMATURE) {
2228                                                 if (G.qual==0)
2229                                                         hide_selected_armature_bones();
2230                                                 else if (G.qual==LR_SHIFTKEY)
2231                                                         hide_unselected_armature_bones();
2232                                                 else if (G.qual==LR_ALTKEY)
2233                                                         show_all_armature_bones();
2234                                         }
2235                                 }
2236                                 else if(FACESEL_PAINT_TEST)
2237                                         hide_tface();
2238                                 else if(G.f & G_PARTICLEEDIT) {
2239                                         if(G.qual == LR_ALTKEY)
2240                                                 PE_hide(0);
2241                                         else if(G.qual == LR_SHIFTKEY)
2242                                                 PE_hide(1);
2243                                         else if(G.qual == 0)
2244                                                 PE_hide(2);
2245                                 }
2246                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2247                                         if (G.qual==0)
2248                                                 hide_selected_pose_bones();
2249                                         else if (G.qual==LR_SHIFTKEY)
2250                                                 hide_unselected_pose_bones();
2251                                         else if (G.qual==LR_ALTKEY)
2252                                                 show_all_pose_bones();
2253                                 }
2254                                 /* Object mode only, other modes are accounted for above */
2255                                 else if ((G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
2256                                         if(G.qual==LR_CTRLKEY)hookmenu();
2257                                         else if(G.qual==LR_ALTKEY) show_objects();
2258                                         else if(G.qual==LR_SHIFTKEY) hide_objects(0);
2259                                         else hide_objects(1);
2260                                 }
2261                                 break;
2262                         case IKEY:
2263                                 if(G.qual==LR_CTRLKEY) {
2264                                         if((ob) && (ob->flag & OB_POSEMODE) && (ob->type==OB_ARMATURE))
2265                                                 deselectall_posearmature(ob, 3, 1);
2266                                         else if(ob && G.obedit) {
2267                                                 if(G.obedit->type == OB_ARMATURE)
2268                                                         deselectall_armature(3, 1);
2269                                                 else
2270                                                         selectswap_mesh();
2271                                         }
2272                                         else
2273                                                 selectswap();
2274                                 }
2275                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY)) {
2276                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2277                                                 pose_clear_IK();
2278                                 }
2279                                 else if(G.qual==LR_SHIFTKEY) {
2280                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2281                                                 pose_add_IK();
2282                                 }
2283                                 break;
2284                                 
2285                         case JKEY:
2286                                 if(G.qual==LR_CTRLKEY) {
2287                                         if( ob ) {
2288                                                 join_menu();
2289                                         }
2290                                         else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
2291                                                 addsegment_nurb();
2292                                         } else {
2293                                                 error("Can't join unless there is an active object");
2294                                         }
2295                                         
2296                                 }
2297                                 else if(G.obedit) {
2298                                         if(G.obedit->type==OB_MESH) {
2299                                                 join_triangles();
2300                                         }
2301                                 }
2302
2303                                 break;
2304                         case KKEY:
2305                                 if(G.obedit) {
2306                                         if (G.obedit->type==OB_MESH) {
2307                                                 if (G.qual==LR_SHIFTKEY)
2308                                                         KnifeSubdivide(KNIFE_PROMPT);
2309                                                 else if (G.qual==0)
2310                                                         LoopMenu();
2311                                         }
2312                                         else if(G.obedit->type==OB_SURF)
2313                                                 printknots();
2314                                 }
2315                                 else {
2316                                         if((G.qual==LR_SHIFTKEY)) {
2317                                                 if(FACESEL_PAINT_TEST)
2318                                                         if (G.f & G_WEIGHTPAINT)
2319                                                                 clear_wpaint_selectedfaces();
2320                                                         else
2321                                                                 clear_vpaint_selectedfaces();
2322                                                 else if(G.f & G_VERTEXPAINT)
2323                                                         clear_vpaint();
2324                                                 else
2325                                                         select_select_keys();
2326                                         }
2327                                         else if (G.qual==0)
2328                                                 set_ob_ipoflags();
2329                                 }
2330                                 
2331                                 break;
2332                         case LKEY:
2333                                 if(G.obedit) {
2334                                         if(G.obedit->type==OB_MESH) {
2335                                                 if (G.qual & LR_CTRLKEY) {
2336                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2337                                                                 selectconnected_mesh_all(); /* normal select linked */
2338                                                         } else {
2339                                                                 selectconnected_delimit_mesh_all(); /* select linked with edge crease delimiting */
2340                                                         }
2341                                                 } else {
2342                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2343                                                                 selectconnected_mesh();
2344                                                         } else {
2345                                                                 selectconnected_delimit_mesh();
2346                                                         }
2347                                                 }
2348                                         }
2349                                         if(G.obedit->type==OB_ARMATURE)
2350                                                 selectconnected_armature();
2351                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
2352                                                 selectconnected_nurb();
2353                                 }
2354                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2355                                         if (G.qual == LR_CTRLKEY) 
2356                                                 poselib_preview_poses(ob, 0);
2357                                         else if (G.qual == LR_SHIFTKEY) 
2358                                                 poselib_add_current_pose(ob, 0);
2359                                         else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
2360                                                 poselib_rename_pose(ob);
2361                                         else if (G.qual == LR_ALTKEY)
2362                                                 poselib_remove_pose(ob, NULL);
2363                                         else
2364                                                 selectconnected_posearmature();
2365                                 }
2366                                 else {
2367                                         if(FACESEL_PAINT_TEST) {
2368                                                 if((G.qual==0))
2369                                                         select_linked_tfaces(0);
2370                                                 else if((G.qual==LR_SHIFTKEY))
2371                                                         select_linked_tfaces(1);
2372                                                 else if(G.qual==LR_CTRLKEY)
2373                                                         select_linked_tfaces(2);
2374                                         }
2375                                         else if(G.f & G_PARTICLEEDIT) {
2376                                                 if(G.qual==0)
2377                                                         PE_select_linked();
2378                                         }
2379                                         else {
2380                                                 if((G.qual==0))
2381                                                         make_local_menu();
2382                                                 else if((G.qual==LR_SHIFTKEY))
2383                                                         selectlinks_menu();
2384                                                 else if(G.qual==LR_CTRLKEY)
2385                                                         make_links_menu();
2386                                         }
2387                                 }
2388                                 break;
2389                         case MKEY:
2390                                 if(G.obedit){
2391                                         if (ELEM(G.qual, 0, LR_SHIFTKEY) && (G.obedit->type==OB_ARMATURE)) {
2392                                                 pose_movetolayer();
2393                                         }
2394                                         else if (G.qual==LR_ALTKEY) {
2395                                                 if (G.obedit->type == OB_MESH) {
2396                                                         mergemenu();
2397                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2398                                                 }
2399                                                 else if (G.obedit->type == OB_ARMATURE) {
2400                                                         merge_armature();
2401                                                 }
2402                                         }
2403                                         else if ((G.qual==0) || (G.qual==LR_CTRLKEY)) {
2404                                                 mirrormenu();
2405                                         }
2406                                         else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2407                                                 if(G.obedit->type==OB_MESH) select_non_manifold();
2408                                         }
2409                                 }
2410                                 else if(G.qual & LR_CTRLKEY) {
2411                                         mirrormenu();
2412                                 }
2413                                 else if(G.qual==0 || G.qual==LR_SHIFTKEY) {
2414                                         if(ob && (ob->flag & OB_POSEMODE))
2415                                                 pose_movetolayer();
2416                                         else
2417                                                 movetolayer();
2418                                 }
2419                                 break;
2420                         case NKEY:
2421                                 if((G.qual==0)) {
2422                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
2423                                         allqueue(REDRAWVIEW3D, 0);
2424                                 }
2425                                 else if(G.obedit) {
2426                                         switch (G.obedit->type){
2427                                         case OB_ARMATURE:
2428                                                 if(G.qual==LR_CTRLKEY) {
2429                                                         pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
2430                                                         if (pupval > 0) {
2431                                                                 auto_align_armature(pupval - 1);
2432                                                                 allqueue(REDRAWVIEW3D, 0);
2433                                                         }
2434                                                 }
2435                                                 break;
2436                                         case OB_MESH: 
2437                                                 if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2438                                                         if(okee("Recalculate normals inside")) {
2439                                                                 righthandfaces(2);
2440                                                                 allqueue(REDRAWVIEW3D, 0);
2441                                                                 BIF_undo_push("Recalculate normals inside");
2442                                                         }
2443                                                 }
2444                                                 else if(G.qual==LR_CTRLKEY){
2445                                                         if(okee("Recalculate normals outside")) {
2446                                                                 righthandfaces(1);
2447                                                                 allqueue(REDRAWVIEW3D, 0);
2448                                                                 BIF_undo_push("Recalculate normals outside");
2449                                                         }
2450                                                 }
2451                                                 break;
2452                                         }
2453                                 }
2454                                 
2455                                 break;
2456                         case OKEY:
2457                                 if (G.obedit || G.f&G_PARTICLEEDIT) {
2458                                         if (G.qual==LR_SHIFTKEY) {
2459                                                 G.scene->prop_mode = (G.scene->prop_mode+1)%7;
2460                                                 allqueue(REDRAWHEADERS, 0);
2461                                         }
2462                                         else if((G.qual==LR_ALTKEY)) {
2463                                                 if(G.scene->proportional==2) G.scene->proportional= 1;
2464                                                 else G.scene->proportional= 2;
2465                                                 allqueue(REDRAWHEADERS, 0);
2466                                         }
2467                                         else if((G.qual==0)) {
2468                                                 G.scene->proportional= !G.scene->proportional;
2469                                                 allqueue(REDRAWHEADERS, 0);
2470                                         }
2471                                 }
2472                                 else if((G.qual==LR_SHIFTKEY || G.qual==(LR_ALTKEY|LR_SHIFTKEY))) {
2473                                         flip_subdivison(-1);
2474                                 }
2475                                 else if(G.qual==LR_ALTKEY) {
2476                                         if(okee("Clear origin")) {
2477                                                 clear_object('o');
2478                                         }
2479                                 }
2480                                 break;
2481
2482                         case PKEY:
2483                                 if(G.obedit) {
2484                                         if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2485                                                 if(G.obedit->type==OB_ARMATURE)
2486                                                         make_bone_parent();
2487                                                 else
2488                                                         make_parent();
2489                                         }
2490                                         
2491                                         else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
2492                                                 clear_bone_parent();
2493                                         else if((G.qual==0) && (G.obedit->type==OB_ARMATURE)) 
2494                                                 armature_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2495                                         else if((G.qual==(LR_CTRLKEY|LR_ALTKEY)) && (G.obedit->type==OB_ARMATURE))
2496                                                 separate_armature();
2497                                         else if((G.qual==0) && G.obedit->type==OB_MESH)
2498                                                 separatemenu();
2499                                         else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
2500                                                 separate_nurb();
2501                                         else if (G.qual==LR_SHIFTKEY) {
2502                                                 initTransform(TFM_PUSHPULL, CTX_NONE);
2503                                                 Transform();
2504                                         }
2505                                 }
2506                                 else if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
2507                                         make_parent();
2508                                 else if(G.qual==LR_SHIFTKEY) {
2509                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
2510                                         doredraw= 1;
2511                                 }
2512                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) {
2513                                         initTransform(TFM_PUSHPULL, CTX_NONE);
2514                                         Transform();
2515                                 }
2516                                 else if(G.qual==LR_ALTKEY)
2517                                         clear_parent();
2518                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
2519                                         make_proxy();
2520                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
2521                         start_RBSimulation();
2522                                 }
2523                                 else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE))
2524                                         pose_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2525                                 else if((G.qual==0)) {
2526                         start_game();
2527                                 }
2528                                 break;                          
2529                         case RKEY:
2530                                 if((G.obedit==0) && G.qual==LR_ALTKEY) {
2531                                         if(okee("Clear rotation")) {
2532                                                 clear_object('r');
2533                                         }
2534                                 } 
2535                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2536                                         v3d->twtype= V3D_MANIP_ROTATE;
2537                                         doredraw= 1;
2538                                 }
2539                                 else if (G.obedit) {
2540                                         if((G.qual==LR_SHIFTKEY)) {
2541                                                 if ELEM(G.obedit->type,  OB_CURVE, OB_SURF)                                     
2542                                                         selectrow_nurb();
2543                                         }
2544                                         else if(G.qual==LR_CTRLKEY) {
2545                                                 if (G.obedit->type==OB_MESH) {
2546                                                         CutEdgeloop(1);
2547                                                         BIF_undo_push("Cut Edgeloop");
2548                                                 }
2549                                                 else if (G.obedit->type==OB_ARMATURE) {
2550                                                         initTransform(TFM_BONE_ROLL, CTX_NONE);
2551                                                         Transform();
2552                                                 }
2553                                         }
2554                                         else if((G.qual==0)) {
2555                                                 initTransform(TFM_ROTATION, CTX_NONE);
2556                                                 Transform();
2557                                         }
2558                                 }
2559                                 else if((G.qual==0)) {
2560                                         initTransform(TFM_ROTATION, CTX_NONE);
2561                                         Transform();
2562                                 }
2563                                 break;
2564                         case SKEY:
2565                                 if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2566                                         v3d->twtype= V3D_MANIP_SCALE;
2567                                         doredraw= 1;
2568                                 }
2569                                 else if(G.obedit) {
2570                                         
2571                                         if(G.qual==LR_ALTKEY) {
2572                                                 if(G.obedit->type==OB_ARMATURE) {
2573                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2574                                                 }
2575                                                 else if (G.obedit->type==OB_CURVE) {
2576                                                         initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
2577                                                 } else {
2578                                                         initTransform(TFM_SHRINKFATTEN, CTX_NONE);
2579                                                 }
2580                                                 Transform();
2581                                         }
2582                                         else if(G.qual==LR_CTRLKEY) {
2583                                                 initTransform(TFM_SHEAR, CTX_NONE);
2584                                                 Transform();
2585                                         }
2586                                         else if(G.qual==LR_SHIFTKEY)
2587                                                 snapmenu();
2588                                         else if(G.qual==0) {
2589                                                 if(G.obedit->type==OB_ARMATURE) {
2590                                                         bArmature *arm= G.obedit->data;
2591                                                         if(arm->drawtype==ARM_ENVELOPE)
2592                                                                 initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
2593                                                         else
2594                                                                 initTransform(TFM_RESIZE, CTX_NONE);
2595                                                 }
2596                                                 else
2597                                                         initTransform(TFM_RESIZE, CTX_NONE);
2598                                                 Transform();
2599                                         }
2600                                         else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
2601                                                 initTransform(TFM_TOSPHERE, CTX_NONE);
2602                                                 Transform();
2603                                         }
2604                                         if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2605                                                 if(G.obedit->type==OB_MESH) select_sharp_edges();
2606                                         }
2607                                 }
2608                                 else if(G.qual==LR_ALTKEY) {
2609                                         if(G.f & G_WEIGHTPAINT)
2610                                                 ob= ob->parent;
2611                                         if(ob && (ob->flag & OB_POSEMODE)) {
2612                                                 bArmature *arm= ob->data;
2613                                                 if( arm->drawtype==ARM_ENVELOPE) {
2614                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2615                                                         Transform();
2616                                                         break;
2617                                                 }
2618                                         }
2619                                         
2620                                         if(okee("Clear scale")) {
2621                                                 clear_object('s');
2622                                         }
2623                                 }
2624                                 else if(G.qual==LR_SHIFTKEY) {
2625                                         snapmenu();
2626                                 }
2627                                 else if((G.qual==0)) {
2628                                         initTransform(TFM_RESIZE, CTX_NONE);
2629                                         Transform();
2630                                 }
2631                                 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2632                                         initTransform(TFM_TOSPHERE, CTX_NONE);
2633                                         Transform();
2634                                 }
2635                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)) {
2636                                         initTransform(TFM_SHEAR, CTX_NONE);
2637                                         Transform();
2638                                 }
2639                                 break;
2640                         case TKEY:
2641                                 if(G.qual == LR_SHIFTKEY) { /* toggle texture in solid draw mode */
2642                                         G.vd->flag2 ^= V3D_SOLID_TEX;
2643                                         allqueue(REDRAWVIEW3D, 0);
2644                                 } else if(G.obedit){
2645                                         if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
2646                                                 convert_to_triface(G.qual & LR_SHIFTKEY);
2647                                                 allqueue(REDRAWVIEW3D, 0);
2648                                                 if (EM_texFaceCheck())
2649                                                         allqueue(REDRAWIMAGE, 0);
2650                                                 
2651                                                 countall();
2652           &nbs